c++ - 带有向量的类构造函数中的析构函数调用
问题描述
我有以下类,它简单地包装一个数组并使用构造函数向其中添加一些元素:
class myArray {
public:
myArray();
myArray(int a, int b);
myArray(int a, int b, int c);
myArray(myArray&& emplace);
~myArray();
int& operator [](int id);
private:
int *data;
};
myArray::myArray() {
data = new int[1];
data[0] = 0;
}
myArray::myArray(int a, int b) {
data = new int[3];
data[0] = 0;
data[1] = a;
data[2] = b;
}
myArray::myArray(int a, int b, int c) {
data = new int[4];
data[0] = 0;
data[1] = a;
data[2] = b;
data[3] = c;
}
myArray::~myArray() {
std::cout << "Destructor"<<std::endl;
delete[] data;
}
int& myArray::operator [](int id) {
return data[id];
}
myArray::myArray(myArray&& emplace) : data(std::move(emplace.data)) {}
此外,我还有第二类,其中包含第一类 ( myArray
) 的元素向量。
class Queue {
public:
Queue();
private:
std::vector<myArray> _queue;
};
Queue::Queue {
_queue.reserve(1000);
for(int a = 0; a < 10; a++)
for(int b = 0; b < 10; b++)
for(int c = 0; c < 10; c++)
_queue.emplace_back(a,b,c);
}
我的问题是:为什么在 Queue 构造函数的末尾为 myArray 元素调用析构函数?Queue 对象在我的主程序中仍然存在,但 myArray 的析构函数释放了分配的内存,因此我得到了分段错误。
有没有办法避免调用析构函数,或者直到队列对象生命周期结束时才调用它?
解决方案
您的移动构造函数不会data
在移动的对象上设置为 null,因此当移动的对象被破坏时,它将尝试释放数据。
如果你有 c++14,你可以std::exchange
用来实现这个:
myArray::myArray(myArray&& emplace)
: data{std::exchange(emplace.data, nullptr)})
{}
否则你需要这样做:
myArray::myArray(myArray&& emplace)
: data{emplace.data)
{
emplace.data = nullptr;
}
移动构造函数将被调用,std::vector
因为它会在您调用时重新分配以增加其容量emplace_back
。执行以下步骤:
- 分配新内存来保存元素
- 使用从前一个内存中的元素放置新内存中的新元素来移动构造
- 销毁前一个内存中的元素
- 释放之前的内存
推荐阅读
- python - 使用 Python-Docx 获取 docx 文件中列表项的列表编号
- c - CS50 第 4 周内存,fread 如何知道移动到文件的下一个字节?
- spring-boot - Spring Cloud Gateway 认证授权
- r - 运行 R 闪亮应用程序出现问题 - staticPath 错误
- xamarin.forms - 在 DatePicker 中更改颜色
- flutter - 如何让用户在开放的街道地图上构建多边形?
- asp.net-core-mvc - 选定的下拉值如何从视图组件保存到主模型?
- javascript - 如何从 html 获取和发送值
- java - 如何将 JComboBox 与数据库值进行比较
- azure - Azure 应用程序网关 - 如何控制不同应用程序的流量