繁体   English   中英

为什么doenst STL vector会在分配时调用默认构造函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM