【发布时间】:2014-12-15 20:10:18
【问题描述】:
我试图了解隐式类成员初始化对于成员 {POD 结构、POD 类和 POD} 的工作原理。在阅读了一些之后,我希望它们被初始化为它们的默认值,但这里的实际行为似乎有所不同 -
#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> >();
}
明显的运行结果不足以说明 POD 是初始化为默认值 0 还是仅包含噪声。但无论如何,这里有一些结果:
使用 gcc 4.6.3 #define SKIP_S1C1 在 ubuntu 上构建并运行它,我明白了
!: s = (0x7ffffe557770, 4196620) a = 1
!: s = (0, 0) a = 1
!: s = (0, 0) a = 1
!: s = (0, 0) a = 1
!: s = (0x1, 6299744) a = 6299744
!: s = (0, 0) a = 6299744
!: s = (0, 0) a = 6299744
!: s = (0, 0) a = 6299744
!: s = (0x1, 6299744) 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
!: 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
当涉及到 {POS 结构、POD 类和 POD} 成员的隐式初始化时,我真的很想了解我应该期待什么以及何时是 UB。任何帮助将不胜感激... :)
【问题讨论】:
-
标量不是隐式值初始化的,用户定义的类是。
标签: c++ constructor