std :: vector和Constructors

时间:2011-06-02 23:45:22

标签: c++ object vector constructor

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

如果对象在构建之后具有未知大小,它如何知道要分配多少内存?

2 个答案:

答案 0 :(得分:7)

至少要编译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默认构造

     

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

答案 1 :(得分:1)

修复错误后会发生什么:

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

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


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

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