简体   繁体   English

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

[英]Why doenst STL vector call default constructor on allocation?

I got the follwing block of code: 我得到了以下代码块:

#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();
}

This code leads to the output: 此代码导致输出:

Default Constructor 默认构造函数

Do Important Stuff 做重要的东西

Default Constructor 默认构造函数

Do Important Stuff 做重要的东西

Do Important Stuff 做重要的东西

Basicly I wanted to write a class, which owns memory but allocates this memory only when I call Create() . 基本上我想写一个类,它拥有内存但只在我调用Create()时才分配这个内存。 To avoid memory leaks and to avoid deleting not allocated memory I introduced wasCreated which will be only true when i call Create() . 为了避免内存泄漏并避免删除未分配的内存,我引入了wasCreated ,这只有在调用Create()时才会wasCreated Every TestStruct should be saved in one vector. 每个TestStruct都应保存在一个向量中。 So in implemented move assigment & ctor and deleted both copy assigment & ctor. 所以在实施移动分配&ctor并删除了复制分配和ctor。

Now it seems to me that the vector doenst call interally the default constructor of my TestStruct when its allocates new memory. 现在在我看来,当我的TestStruct分配新内存时,向量doenst会调用我的TestStruct的默认构造函数。 Why is so and how do get the vector to call the default constructor on memory allocation? 为什么会这样,如何让向量在内存分配上调用默认构造函数? Do I need my own allocator? 我需要自己的分配器吗?

Your problem is that your move constructor is implemented incorrectly. 您的问题是您的移动构造函数实现不正确。 It swaps wasCreated between the newly created object and the one being moved from, but the variable in the newly created object has not been initialized yet (a default-constructed bool has an unknown value). 它在新创建的对象和正在移动的对象之间交换wasCreated ,但新创建的对象中的变量尚未初始化 (默认构造的bool具有未知值)。 So your temporary objects created with TestStruct() receive an uninitialized bool, which happens to be true in your case, hence the calls to DoImportantStuff() in their destructors. 因此,使用TestStruct()创建的临时对象会收到一个未初始化的bool,在您的情况下恰好是true ,因此在它们的析构函数中调用DoImportantStuff()

So the move constructor should look something like this: 所以移动构造函数应该看起来像这样:

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

(You have moved ownership to the newly created object, the old one doesn't own anything anymore.) (您已将所有权移至新创建的对象,旧的对象不再拥有任何内容。)

Don't confuse the assignment operator with the constructor; 不要将赋值运算符与构造函数混淆; they do different things. 他们做不同的事情。 The assignment operator deals with two objects that are both already constructed ; 赋值运算符处理两个已经构造的对象; in the case of the constructor, the object being constructed is, well..., not constructed yet, so it doesn't have a valid state. 在构造函数的情况下,正在构造的对象是......,还没有构造,因此它没有有效的状态。

By the way, emplace_back() is pointless the way you're using it. 顺便说一句, emplace_back()与你使用它的方式毫无意义。 Its purpose is to forward its arguments directly to the constructor of the object inside the vector. 其目的是将其参数直接转发给向量内对象的构造函数。 Since you have a default constructor (no arguments), the call should be: 由于您有默认构造函数(无参数),因此调用应为:

testVector.emplace_back();

This will default-construct the TestStruct in place. 这将默认构建TestStruct

Now it seems to me that the vector doenst call interally the default constructor of my TestStruct when its allocates new memory. 现在在我看来,当我的TestStruct分配新内存时,向量doenst会调用我的TestStruct的默认构造函数。

A default-constructed vector has zero size, so there are no objects to construct. 默认构造的向量大小为零,因此没有要构造的对象。

If you want the vector to default-construct some objects, resize it. 如果您希望向量默认构造一些对象,请调整其大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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