C++ c++;(POD结构、POD类和POD)成员的隐式类成员初始化
我试图理解隐式类成员初始化如何为成员{POD structs、POD类和POD}工作。在阅读了一些内容后,我希望它们被初始化为默认值,但实际行为在这里似乎有所不同-C++ c++;(POD结构、POD类和POD)成员的隐式类成员初始化,c++,constructor,C++,Constructor,我试图理解隐式类成员初始化如何为成员{POD structs、POD类和POD}工作。在阅读了一些内容后,我希望它们被初始化为默认值,但实际行为在这里似乎有所不同- #include <iostream> struct S1 { void* a; int b; }; struct S2 { S2() { std::cout << "!"; } void* a; int b; }; struct S3 { S3() :
#include <iostream>
struct S1
{
void* a;
int b;
};
struct S2
{
S2() { std::cout << "!"; }
void* a;
int b;
};
struct S3
{
S3() : a(), b() { std::cout << "!"; }
void* a;
int b;
};
class C1
{
public:
void* a;
int b;
};
class C2
{
public:
C2() { std::cout << "!"; }
void* a;
int b;
};
class C3
{
public:
C3() : a(), b() { std::cout << "!"; }
void* a;
int b;
};
template <typename T>
class FOO1
{
public:
T s;
int a;
};
template <typename T>
class FOO2
{
public:
FOO2() {}
T s;
int a;
};
template <typename T>
class FOO3
{
public:
FOO3() : s(), a() {}
T s;
int a;
};
//#define SKIP_S1C1
template <typename T>
void moo()
{
#ifndef SKIP_S1C1
T* f = new T();
T foo = *f;
std::cout << ":\ts = (" << foo.s.a << ", " << foo.s.b << ")\ta = " << foo.a << std::endl;
delete f;
#else
T foo;
std::cout << ":\ts = (" << foo.s.a << ", " << foo.s.b << ")\ta = " << foo.a << std::endl;
#endif
}
int main()
{
#ifndef SKIP_S1C1
moo<FOO1<S1> >();
#endif
moo<FOO1<S2> >();
moo<FOO1<S3> >();
#ifndef SKIP_S1C1
moo<FOO1<C1> >();
#endif
moo<FOO1<C2> >();
moo<FOO1<C3> >();
std::cout << std::endl;
#ifndef SKIP_S1C1
moo<FOO2<S1> >();
#endif
moo<FOO2<S2> >();
moo<FOO2<S3> >();
#ifndef SKIP_S1C1
moo<FOO2<C1> >();
#endif
moo<FOO2<C2> >();
moo<FOO2<C3> >();
std::cout << std::endl;
#ifndef SKIP_S1C1
moo<FOO3<S1> >();
#endif
moo<FOO3<S2> >();
moo<FOO3<S3> >();
#ifndef SKIP_S1C1
moo<FOO3<C1> >();
#endif
moo<FOO3<C2> >();
moo<FOO3<C3> >();
}
当它被评论掉的时候,我得到了
: s = (0, 0) a = 0
!: s = (0, 0) a = 0
!: s = (0, 0) a = 0
: s = (0, 0) a = 0
!: s = (0, 0) a = 0
!: s = (0, 0) a = 0
: s = (0, 0) a = 0
!: s = (0, 0) a = 0
!: s = (0, 0) a = 0
: s = (0, 0) a = 0
!: s = (0, 0) a = 0
!: s = (0, 0) a = 0
: s = (0, 0) a = 0
!: s = (0, 0) a = 0
!: s = (0, 0) a = 0
: s = (0, 0) a = 0
!: s = (0, 0) a = 0
!: s = (0, 0) a = 0
有了VS2013,有了它的评论
: s = (00000000, 0) a = 0
!: s = (CDCDCDCD, -842150451) a = -842150451
!: s = (00000000, 0) a = -842150451
: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
: s = (CDCDCDCD, -842150451) a = -842150451
!: s = (CDCDCDCD, -842150451) a = -842150451
!: s = (00000000, 0) a = -842150451
: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
: s = (00000000, 0) a = 0
!: s = (CDCDCDCD, -842150451) a = 0
!: s = (00000000, 0) a = 0
: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (CCCCCCCC, -858993460) a = -858993460
!: s = (00000000, 0) a = -858993460
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (CCCCCCCC, -858993460) a = -858993460
!: s = (00000000, 0) a = -858993460
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (CCCCCCCC, -858993460) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
和未注释
: s = (00000000, 0) a = 0
!: s = (CDCDCDCD, -842150451) a = -842150451
!: s = (00000000, 0) a = -842150451
: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
: s = (CDCDCDCD, -842150451) a = -842150451
!: s = (CDCDCDCD, -842150451) a = -842150451
!: s = (00000000, 0) a = -842150451
: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
: s = (00000000, 0) a = 0
!: s = (CDCDCDCD, -842150451) a = 0
!: s = (00000000, 0) a = 0
: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (CCCCCCCC, -858993460) a = -858993460
!: s = (00000000, 0) a = -858993460
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (CCCCCCCC, -858993460) a = -858993460
!: s = (00000000, 0) a = -858993460
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (CCCCCCCC, -858993460) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
!: s = (00000000, 0) a = 0
我真的很想了解当涉及到{POS struct、POD类和POD}成员的隐式初始化时,我应该期望什么以及何时需要UB。任何帮助都将不胜感激……:) 构造函数很复杂,细节是技术性的,但这里有一个通用摘要*: 有三种初始化方法:
- 零初始化-细节是技术性的,但有效地将所有位设置为零。这绕过了构造函数
- 默认初始化-如果它有构造函数,则调用默认构造函数。否则,不会发生初始化阅读这些内容就是您找到的UB。
- 值初始化-如果它有构造函数,则调用默认构造函数。否则,其位全部(有效)设置为零
- 静态全局变量-初始化为零,然后初始化值。(非常奇怪)
- 局部变量-默认值已初始化
newt代码>-默认初始化
newt()代码>-值初始化
- 成员不在初始列表中-默认初始化
- 初始化列表中的成员-值初始化
**是的,它的“初始化”是“没有初始化”,这使得关于“如果它被初始化”的其他段落在技术上模糊不清,但应用了常识。它没有初始化。标量不是隐式值初始化的,用户定义的类是。啊,谢谢你,这是一个完美的总结,回答了我所有的问题,包括测试代码中试图涵盖的其他一些问题,即使没有明确问到…)如果可以的话,只是一个小小的澄清-在结构和类构造函数之间没有区别,对吗?我承认我只浏览了代码,如果代码中有任何特定的测试仍然让人困惑,请告诉我,我会尝试找出其中的一部分。@Guest86:
struct
和class
之间唯一的区别是继承和成员在struct
中默认为public
。除了那个微小的细节,它们是100%相同的。大多数人将class
用于复杂的事物,而将struct
用于“普通的旧数据”,但这并没有真正的理由。