值初始化
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中的条件,两个类都没有用户声明的构造函数、虚拟函数、虚拟基类、带初始化器的成员或类类型的成员;CCD_ 3没有基类,而CCD_。
但是,我如何观察对B隐式声明的构造函数的调用,并确保我的编译器正在调用它呢?
使类具有隐式但非平凡的默认构造函数的一种方法是具有非平凡的成员或基类:
struct A {
// A user-declared constructor is non-trivial
A() {std::cout << "Construct An";}
};
struct B : A {};
现在,您可以(间接(观察B
的隐式构造函数被调用,方法是观察它调用A
的构造函数时的副作用。
N3797之后的说明:
如果函数是用户声明的而不是显式的,那么它就是用户提供的在其第一次声明时默认或删除。
因此,由于您没有为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
的构造函数,这将最终导致构造成员。
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员