[英]Why doenst STL vector call default constructor on allocation?
我得到了以下代码块:
#include <vector>
#include <iostream>
struct TestStruct {
bool wasCreated;
TestStruct() {
std::cout << "Default Constructor" << std::endl;
wasCreated = false;
}
~TestStruct() {
if (wasCreated) {
DoImportantStuff();
}
}
void Create() {
wasCreated = true;
}
// delete all copy stuff
TestStruct(const TestStruct&) = delete;
TestStruct& operator=(const TestStruct&) = delete;
// implement only move assignment & ctor
TestStruct(TestStruct&& other) {
std::swap(wasCreated, other.wasCreated);
}
TestStruct& operator=(TestStruct&& other) {
std::swap(wasCreated, other.wasCreated);
return *this;
}
// very important stuff
void DoImportantStuff() {
std::cout << "Do Important Stuff" << std::endl;
}
};
int main() {
std::vector<TestStruct> testVector;
testVector.emplace_back(TestStruct());
testVector.emplace_back(TestStruct());
std::cin.get();
}
此代码导致输出:
默认构造函数
做重要的东西
默认构造函数
做重要的东西
做重要的东西
基本上我想写一个类,它拥有内存但只在我调用Create()
时才分配这个内存。 为了避免内存泄漏并避免删除未分配的内存,我引入了wasCreated
,这只有在调用Create()
时才会wasCreated
。 每个TestStruct都应保存在一个向量中。 所以在实施移动分配&ctor并删除了复制分配和ctor。
现在在我看来,当我的TestStruct分配新内存时,向量doenst会调用我的TestStruct的默认构造函数。 为什么会这样,如何让向量在内存分配上调用默认构造函数? 我需要自己的分配器吗?
您的问题是您的移动构造函数实现不正确。 它在新创建的对象和正在移动的对象之间交换wasCreated
,但新创建的对象中的变量尚未初始化 (默认构造的bool具有未知值)。 因此,使用TestStruct()
创建的临时对象会收到一个未初始化的bool,在您的情况下恰好是true
,因此在它们的析构函数中调用DoImportantStuff()
。
所以移动构造函数应该看起来像这样:
// implement only move assignment & ctor
TestStruct(TestStruct&& other) : wasCreated(other.wasCreated) {
other.wasCreated = false;
}
(您已将所有权移至新创建的对象,旧的对象不再拥有任何内容。)
不要将赋值运算符与构造函数混淆; 他们做不同的事情。 赋值运算符处理两个已经构造的对象; 在构造函数的情况下,正在构造的对象是......,还没有构造,因此它没有有效的状态。
顺便说一句, emplace_back()
与你使用它的方式毫无意义。 其目的是将其参数直接转发给向量内对象的构造函数。 由于您有默认构造函数(无参数),因此调用应为:
testVector.emplace_back();
这将默认构建TestStruct
。
现在在我看来,当我的TestStruct分配新内存时,向量doenst会调用我的TestStruct的默认构造函数。
默认构造的向量大小为零,因此没有要构造的对象。
如果您希望向量默认构造一些对象,请调整其大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.