为什么空向量调用值类型的默认构造函数?

时间:2011-06-27 03:26:08

标签: c++ stl vector stdvector

使用g ++,我发现创建一个大小为零的向量会调用向量的参数化对象类型的构造函数一次。然后它被删除。为什么会这样?

#include <iostream>
#include <vector>
using namespace std;

class s
{
    public:
    s() { cout << endl << "default s constructor" << endl; }
    ~s() { cout << endl << "default s destructor" << endl; }

};

int main()
{
    vector<s> v(0);
}

输出:

默认构造函数

默认的析构函数

2 个答案:

答案 0 :(得分:29)

因为您显式传递了一个初始大小,该大小调用的构造函数具有另一个默认值为s()的参数。只需忽略(0)(即std::vector<s> v;),就不会发生这种情况。

为完整起见,标准23.2.4-2将您调用的构造函数定义为:

explicit vector(size_type n, const T& value = T() ,
const Allocator& = Allocator());

除了(与C ++ 03相关但不与C ++ 11相关)

这个构造函数的另一个有趣的行为方面也引起了对S.O.的关注。周期性地:当所请求的元素的初始数量是> 0,它将原型参数中的那些元素复制构造到构造函数:

  • 人们经常会使用一个默认的构造函数来保留未初始化的成员变量,希望使vector(n)几乎和底层的免费商店分配一样快,但是
  • 复制构造函数仍被调用n次,以将原型对象的“垃圾”内容复制到每个请求的元素中

这具有明显的性能成本,但是如果垃圾内容包括例如,则还可能使应用程序崩溃。复制构造函数只能假设的指针是有效的。类似地,即使push_back这样一个未初始化的垃圾对象也是非常危险的 - 它缺乏适当的值语义封装,并且可能在向量调整大小时被复制,像向量等执行算法操作如std::sort()。< / p>

答案 1 :(得分:10)

您正在调用的实际构造函数是(来自cplusplus.com):

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

因此,即使您只指定了大小,也会为第二个参数创建一个新的T对象,因此也会在构造函数结束时销毁它。