如果我没有在 C++ 中的类或任何其他构造函数中定义默认构造函数,我已经读到编译器会为您创建默认构造函数。但是我创建了一个测试类,将其编译为汇编代码并检查发现没有创建任何类型的代码。
有人可以澄清默认构造函数的代码是如何创建的,还是首先创建的?
4 回答
如果需要,将创建默认构造函数,例如:
class Foo {
std::string s;
};
...
Foo f;
12.1:
默认构造函数 (12.1)、复制构造函数和复制赋值运算符 (12.8) 和析构函数 (12.4) 是特殊的成员函数。当程序没有显式声明它们时,实现将为类类型隐式声明这些成员函数,除非在 12.1 中注明。如果使用它们,实现将隐式定义它们,如 12.1、12.4 和 12.8 中所指定。
此外,如果您的类不需要在构造函数中执行任何操作,编译器可能会选择不生成代码,即使按照标准构造函数应该存在。
C++ != 汇编。
汇编是(一种可能的)已编译 C++ 程序的输出,它可能包含也可能不包含某些优化,这些优化可能会省略对可能为空的构造函数的调用。
换句话说,该语言说有一个默认构造函数,但它只描述行为,而不是实现。如果一个实现感觉它不需要生成代码,它就没有必要。
这是 C++03 标准所说的:
§12.1/5:
类 X 的默认构造函数是类 X 的构造函数,可以在没有参数的情况下调用。如果类 X 没有用户声明的构造函数,则隐式声明默认构造函数。隐式声明的默认构造函数是其类的内联公共成员。如果构造函数是隐式声明的默认构造函数并且满足以下条件,则构造函数是微不足道的:
- 它的类没有虚函数 (10.3) 和虚基类 (10.1),并且
- 其类的所有直接基类都有普通的构造函数,并且
- 对于其类的所有属于类类型(或其数组)的非静态数据成员,每个这样的类都有一个普通的构造函数。
§12.1/6:
否则,构造函数是不平凡的。
§12.1/7:
一个类的隐式声明的默认构造函数在用于创建其类类型(1.8)的对象时被隐式定义。隐式定义的默认构造函数执行类的一组初始化,这些初始化将由用户编写的具有空 mem-initializer-list (12.6.2) 和空函数体的类的默认构造函数执行。如果该用户编写的默认构造函数格式错误,则程序格式错误。在隐式定义类的隐式声明的默认构造函数之前,应隐式定义其基类及其非静态数据成员的所有隐式声明的默认构造函数。[注意:隐式声明的默认构造函数具有异常规范 (15.4)。]
这意味着对于具有隐式声明但未隐式定义的默认构造函数的类,或者对于具有隐式定义的普通默认构造函数的类,可能不需要代码生成。
您是否想问一下您的编译器是否真的为默认构造函数发出代码?
这取决于优化。大多数现代编译器在与 -O0 一起使用时会发出默认的构造函数代码序列,但如果它未使用并且您使用 -O2 或更高版本,则会对其进行优化。