[英]Value initialization
$ 8.5 / 7表示
- 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数。
我无法理解这句话的最后一部分“如果T隐式声明的默认构造函数是非平凡的,那么构造函数就被调用了。”
有人可以用一个例子解释一下吗?
class A
{
int x;
};
class B : A {};
B b{};
我认为上面代码中的B
有一个非平凡的构造函数。 但是我如何观察对B
的隐式声明的构造函数的调用并确保我的编译器正在调用它?
我认为上面代码中的B有一个非平凡的构造函数。
在您的示例中,构造函数是微不足道的。
查看C ++ 11 12.1 / 5中的条件,这两个类都没有用户声明的构造函数,虚函数,虚基类,具有初始化的成员或类类型的成员; A
没有基类, B
只有一个普通的基类。
但是我如何观察对B的隐式声明的构造函数的调用并确保我的编译器正在调用它?
使用隐式但非平凡的默认构造函数创建类的一种方法是使用一个非平凡的成员或基类:
struct A {
// A user-declared constructor is non-trivial
A() {std::cout << "Construct A\n";}
};
struct B : A {};
现在,您可以(间接)观察被调用的B
的隐式构造函数,方法是在调用A
的构造函数时观察副作用。
如果函数是用户声明的,并且在第一个声明中未明确默认或删除,则用户提供该函数。
因此,由于您没有为B
声明默认构造函数,因此不是用户提供的。 以下适用:
如果默认构造函数不是用户提供的,则默认构造函数是微不足道的,如果:
- 它的类没有虚函数(10.3),没有虚基类(10.1),和
- 其类中没有非静态数据成员具有大括号或等于初始化程序 ,并且
- 它的类的所有直接基类都有普通的默认构造函数,和
- 对于类类的所有非静态数据成员(或其数组),每个这样的类都有一个普通的默认构造函数。
所以它确实是微不足道的,因为我们可以递归地为A
应用相同的过程。
struct A { A() = default; }; // Trivial default constructor!
struct A { A() = delete; }; // Also trivial!
struct A { A(); }; // Can't be trivial!
struct B { virtual void f(); }
struct A : B {}; // Non-trivial default constructor.
struct B {};
struct A : virtual B {}; // Non-trivial default constructor.
想象一下,你有这个
struct A {
string a;
int value;
};
int main() {
A a = A();
return a.value;
}
当我们返回该值时, a.value
为零,因为该对象是零初始化的。 但这还不够,因为a
还包含一个具有构造函数的字符串成员。 对于要调用的构造函数,标准安排调用A
的构造函数,这最终将导致构造成员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.