为什么空向量调用值类型的默认构造函数?
Why does an empty vector call the value type's default constructor?
使用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
对象,因此在构造函数结束时也会被销毁。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数