[英]c++ implicit class member initialization for (POD struct, POD class and POD) members
我試圖理解隱式類成員初始化如何為成員{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在ubuntu上構建和運行它#define SKIP_S1C1
取消注釋,我得到
!: 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 struct,POD classes和POD}成員的隱式初始化時它是UB。 任何幫助將不勝感激... :)
構造函數很復雜,細節是技術性的,但這里是一個通用的摘要*:
有三種方法可以初始化:
他們在許多情況下被召喚:
new T;
- 默認初始化 new T();
- 值初始化 有關更多詳細信息,請參閱C ++ 11草案中的第8.5節和第12.6節。 他們漫長而無聊。
另請注意,C的規則在技術上有驚人的不同,盡管效果對我來說是相同的。
*我的摘要在技術上並不准確,但對於大多數實際代碼而言足夠准確。 例如,數組在技術上有特殊的規則,但它們非常直觀,不值得一提。
**是的,它的“初始化”是“沒有初始化”,這使得其他段落“如果它被初始化”在技術上含糊不清,但應用常識。 它沒有初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.