c++ - 为什么 STD vector 在分配时不调用默认构造函数?

标签 c++ vector stl 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();
}

此代码导致输出:

Default Constructor

Do Important Stuff

Default Constructor

Do Important Stuff

Do Important Stuff

基本上我想写一个类,它拥有内存,但只有在我调用 Create() 时才分配内存。为了避免内存泄漏并避免删除未分配的内存,我引入了 wasCreated,只有在我调用 Create() 时才会为真。每个 TestStruct 都应该保存在一个 vector 中。因此,在实现移动分配和构造函数时,删除了复制分配和构造函数。

现在在我看来, vector 在分配新内存时会内部调用我的 TestStruct 的默认构造函数。为什么会这样以及如何让 vector 调用内存分配的默认构造函数?我需要自己的分配器吗?

最佳答案

你的问题是你的移动构造函数实现不正确。它在新创建的对象和被移动的对象之间交换 wasCreated,但是新创建的对象中的变量还没有被初始化(默认构造的 bool 有一个未知值)。因此,您使用 TestStruct() 创建的临时对象会收到一个未初始化的 bool 值,在您的情况下恰好为 true,因此调用 DoImportantStuff() 在它们的析构函数中。

所以移动构造函数应该看起来像这样:

// implement only move assignment & ctor
TestStruct(TestStruct&& other) : wasCreated(other.wasCreated) {
    other.wasCreated = false;
}

(您已将所有权移至新创建的对象,旧对象不再拥有任何东西。)

不要将赋值运算符与构造函数混淆;他们做不同的事情。赋值运算符处理两个都已构造的对象;在构造函数的情况下,正在构造的对象是,好吧......,尚未构造,因此它没有有效状态。

顺便说一句,emplace_back() 是毫无意义的,你正在使用它的方式。其目的是将其参数直接转发给 vector 内对象的构造函数。因为你有一个默认的构造函数(没有参数),调用应该是:

testVector.emplace_back();

这将默认构造 TestStruct

关于c++ - 为什么 STD vector 在分配时不调用默认构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27468606/

相关文章:

c++ - 想要使用 STL 在 C++ 中扫描二维数组

c++ - 以最通用的形式将 map 的第一个元素存储到 vector 中。最佳解决方案

c++ - 使用列表迭代器获取所有值

graphics - 自行车的旋转矩阵

c++ - 按数据成员对对象的 vector 进行排序

c++ - 查询使用随机整数作为 vector 的大小

C++ - 返回 const 对象的 const vector 的 const vector

c++ - 字符串下标是关联索引吗?

c++ - 指针到指针、指向值地址和二维数组访问之间的清晰度

c++ - 为什么编译器需要尾随返回类型?