std::vector and Constructors

std::vector and Constructors

本文关键字:Constructors and vector std      更新时间:2023-10-16

当std::vector为它所包含的对象创建新实例时,它会调用哪个构造函数?我觉得它调用了一个默认构造函数,但如果没有定义一个,或者编译器是为我做的呢?

特别是在这样的情况下:

class Foo
{
    public:
        Foo(int size)
        {
            data = new double[size];
        }

        ~Foo()
        {
            delete[] data;
        }
    private:
        double* data;
};
std::vector<Foo> myVector;
Foo bar(5);
myVector.push_back(bar);
//stuff

当对象在构造之前具有未知大小时,它如何知道要分配多少内存?

至少,对于要编译的std::vector<T>T必须是可复制构造的,并且是可复制分配的。如果要使用std::vector<T>::vector(int)(或std::vector<T>::resize()),则T必须是默认可构造的。如果这些要求中的任何一个没有得到满足,代码将不会编译。

C++03标准,第23.1节(一般讨论集装箱):

存储在这些组件中的对象类型必须满足CopyConstructible类型(20.1.3)的要求,以及Assignable类型的附加要求。

第20.1.4节:

20.1.4默认构造

默认构造函数不是必需的。某些容器类成员函数签名将默认构造函数指定为默认参数。如果使用默认参数(8.3.6)调用其中一个签名,则T()应为定义明确的表达式(8.5)

修复错误后会发生什么:

std::vector<Foo> myVector;
myVector.reserve(10);
myVector.push_back(bar);

您有两个指向同一个data缓冲区的Foo实例。它可能会工作一段时间,但最终两个对象都被销毁,析构函数被调用两次(或更多次,取决于vector是否需要移动其内容),缓冲区被释放两次,从而导致未定义的行为(通常意味着崩溃)。


为了解决vector的初始内容,它复制构造了您作为参数传入的模式(此参数默认为默认构造的对象,但不必是):

std::vector<Foo> myVector(10, bar); // 10 copies of bar