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

Why does an empty vector call the value type's default constructor?

本文关键字:默认 构造函数 类型 向量 调用 为什么      更新时间:2023-10-16

使用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);
}

输出:

默认的s构造函数

默认的s析构函数

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

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

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

旁白(与C++03相关,但与C++11无关)

这个构造函数的另一个有趣的行为方面也会定期向S.O.提出:当请求的初始元素数量>0时,它会将这些元素从原型参数复制到构造函数:

  • 人们经常设置一个默认构造函数,使成员变量不被初始化,希望使vector(n)的速度几乎与底层的免费存储分配一样快,但是
  • 复制构造函数仍然被调用n次,以将原型对象的"垃圾"内容复制到每个请求的元素中

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

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

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

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