Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;(POD结构、POD类和POD)成员的隐式类成员初始化_C++_Constructor - Fatal编程技术网

C++ c++;(POD结构、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() :

我试图理解隐式类成员初始化如何为成员{POD structs、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> >();
}
当它被评论掉的时候,我得到了

:       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()-值初始化
  • 成员不在初始列表中-默认初始化
  • 初始化列表中的成员-值初始化
有关更多详细信息,请参阅C++11草案第§8.5节和第§12.6节。它们又长又无聊

还要注意的是,C的规则在技术上有着惊人的不同,尽管在我看来效果是一样的

*我的总结在技术上并不准确,但对于大多数真实代码来说已经足够准确了。例如,数组在技术上有特殊的规则,但它们非常直观,不值得一提


**是的,它的“初始化”是“没有初始化”,这使得关于“如果它被初始化”的其他段落在技术上模糊不清,但应用了常识。它没有初始化。

标量不是隐式值初始化的,用户定义的类是。啊,谢谢你,这是一个完美的总结,回答了我所有的问题,包括测试代码中试图涵盖的其他一些问题,即使没有明确问到…)如果可以的话,只是一个小小的澄清-在结构和类构造函数之间没有区别,对吗?我承认我只浏览了代码,如果代码中有任何特定的测试仍然让人困惑,请告诉我,我会尝试找出其中的一部分。@Guest86:
struct
class
之间唯一的区别是继承和成员在
struct
中默认为
public
。除了那个微小的细节,它们是100%相同的。大多数人将
class
用于复杂的事物,而将
struct
用于“普通的旧数据”,但这并没有真正的理由。