初始化新对象时C++默认构造函数和 POD 问题
C++ default constructor and POD questions when initializing a new object
我理解默认构造函数和用户提供的空构造函数之间的区别(至少我相信我理解)以及 POD 的含义。但是,在对象初始化过程中,我不太了解一些行为:
#include <iostream>
using namespace std;
//POD
struct A {
int a, b, c;
};
//Not POD
struct B {
B() {};
int a, b, c;
};
int main(){
A a = {1,2,3} \ Case 1. Works, this is how we initialize a POD type
B b1 = {1,2,3} \ Case 2. Doesn't work, since B is not POD
B b2; \ Case 3. Works, call the user provided empty constructor but a, b and c are not initialized
A c{}; \ Case 4. Works, initialize everything to 0
A d; \ Case 5. Doesn't work. This is the case I don't understand
cout << a.a << a.b << a.c << endl;
cout << b1.a << b1.b << b1.c << endl;
cout << b2.a << b2.b << b2.c << endl;
cout << c.a << c.b << c.c << endl;
cout << d.a << d.b << d.c << endl;
}
如上所述,案例5是我不理解的行为。我期待它会调用默认构造函数并将每个成员初始化为 0。但是,我收到编译错误:
错误 C4700 使用未初始化的局部变量"d">
谁能帮我理解为什么它会报告上述错误?我在Windows上运行并使用Visual Studio编译器。
回答问题的另一个方面,即">PODness"。
POD 是一个遗留定义,它不再真正使用,因为它不可能涵盖各种情况。它在 C++20 中已弃用。相反,使用各种术语来讨论类与 C 结构的兼容性(因为最终,这就是它的全部内容)。
特别是,最重要的属性(至少在我看来)是:
标准布局- :这很重要,因为,通俗地说,当类是标准布局时,对象可以被视为一个字节序列,发送到其他程序(可能用不同的语言编写),并在接收端从这个序列重建(在考虑填充之后)。当实体序列化数据通过网络发送或保存到文件时,这起着重要作用 简单可复制
- :这很重要,因为当类是简单可复制的时,只需内存从一个对象复制字节即可从一个对象创建一个对象。这在优化中起着很大的作用 平凡类型,上面平凡
- 可复制要求的扩展:这很重要,因为当类是平凡类型时,任何随机字节序列都可以被视为该类型的有效对象(在考虑内存别名之后)。
Error C4700 uninitialized local variable 'd' used
谁能帮我理解为什么它会报告上述错误?
该错误意味着您(可能?)读取了一个不确定的值。读取不确定值的行为是未定义的(忽略某些明显不适用于您的情况的异常)。
编译器似乎已确定您在初始化之前使用了 (成员)d
的值,并尝试通过诊断问题来提供帮助。
从技术上讲,读取不确定的值不会使程序格式错误,因此不允许阻止编译。您可能已将编译器配置为故意违反标准,在出现警告时拒绝编译。如果没有,那么这可能是编译器中的一致性错误。
解决方案:不要读取不确定的值。您可以将初始化值设置为初始化为零,也可以列出其他值的初始化。请参阅示例案例 1 和 4。
关于命名法的小更正:
案例 3.工作,调用用户提供的空构造函数,但 a、b 和 c 初始化为随机垃圾值
更准确地说:成员未初始化,并且可能剩下 1个不确定的值。
1在您的示例中,您使用静态存储声明变量。这些在动态初始化之前最初为零初始化。因此,在您的示例中,成员没有不确定的值,而是零。
案例 4.工作,通过调用默认构造函数将所有内容初始化为 0
int
没有"默认构造函数"。它们是值初始化的。int
的值初始化为零初始化。
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 构造函数默认公共和私有变量
- 类模板构造函数默认参数
- 构造函数默认参数
- C++模板构造函数默认参数
- 在c++中设置构造函数默认值
- c++构造函数默认参数
- C++构造函数默认值头文件