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
如果对象在构建之后具有未知大小,它如何知道要分配多少内存?
答案 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