Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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++ I';我对这个C+感到困惑+;建造师_C++_Constructor - Fatal编程技术网

C++ I';我对这个C+感到困惑+;建造师

C++ I';我对这个C+感到困惑+;建造师,c++,constructor,C++,Constructor,我试图寻找一个答案,但不确定确切地说,最好的术语来描述这个 我正在读一本关于SFML编程的书,其中一个例子让我对构造函数的用法感到困惑 假设我们有类A和类B。类A有一个类型为B(memberB)的成员变量。的构造函数如下所示: A::A() : OtherMemberType(with, params), memberB() {...} 假设memberB是用初始化列表中的默认构造函数初始化的,那么在列表中显式列出它的目的是什么?如果不把它列入清单,会不会产生同样的效果 谢谢 编辑:谢谢你的回

我试图寻找一个答案,但不确定确切地说,最好的术语来描述这个

我正在读一本关于SFML编程的书,其中一个例子让我对构造函数的用法感到困惑

假设我们有类A和类B。类A有一个类型为B(memberB)的成员变量。的构造函数如下所示:

A::A() : OtherMemberType(with, params), memberB()
{...}
假设memberB是用初始化列表中的默认构造函数初始化的,那么在列表中显式列出它的目的是什么?如果不把它列入清单,会不会产生同样的效果

谢谢

编辑:谢谢你的回答。我现在已经了解了值初始化与默认初始化的(基本)区别

关于更多的上下文,由于提出了“B类可能被破坏”的概念,以下是文本中的代码示例:

在这种情况下,有人知道SFML的一些细节吗?是sf::CircleShape“断开”,还是这是对默认构造函数的冗余调用


Adam

初始化初始化器中的成员并将其列出。从列表中删除它

如果
B
是非聚合的,并且具有默认构造函数,则没有区别

如果
B
是一个集合,则可能存在差异。默认初始化它意味着如果它包含内置项,这些可能无法初始化。值初始化它最终会产生零初始化其成员的效果

这是一个初始化语义不同的示例:

struct B
{
  int i, j, k;
};

struct A
{
  A() : b() {} // value-initializes b: b.i, b.j, b.k zero initialized

  B b;
};

struct AA
{
  AA() {} // default-initializes b: b.i, b.j, b.k have no initialization

  B b;
};

通过将其包括在初始化器列表中,成员的值被初始化。如果不是,它将被默认初始化。是否有差异取决于类型

如果它是一个具有声明的默认构造函数的类类型,那么没有区别:在任何情况下都将使用该构造函数

否则,值初始化将为零初始化基元类型(和类类型的基元成员),而在某些情况下,默认初始化将使它们未初始化,并具有不确定的值


更新:在您的特定情况下,类确实有一个,因此显式初始化是多余的。但冗余不一定是坏事——它表明它是故意进行值初始化的,而不是被遗忘。

鉴于mike和juan所说的,我想说类
B
的实现被破坏了,如果它需要像那样进行值初始化,除非合理预期它会以这种方式运行

通常,给定一个正确设计的类(如果有POD成员,则使用用户提供的默认构造函数iff),初始化类型B的成员的值和默认值之间的行为应该没有区别

某些特殊类可能不会对其成员执行零初始化,并且可能缺少默认构造函数
std::array
就是这样一个类。它们试图保持其实现底层的原始类型的性能。此类类的成员将需要值初始化

有几种可能性:

  • B
    is具有通常的行为—值初始化是多余的。具体而言:

    a) 类
    B
    没有POD类型的成员,而非POD类型的成员类型都是根据可能性#1实现的,或者

    b) 类
    b
    的用户编写的默认构造函数根据需要初始化所有POD类型的成员

  • B
    具有性能优化类型的语义,例如数字类型或原始C数组的替换。它缺少默认构造函数,除非执行值初始化,否则不会初始化。示例:
    std::array
    其中
    T
    是POD

  • Class
    B
    是一个模板参数。在
    B
    上没有任何约束的情况下,值初始化是唯一安全的选择
    B
    毕竟可以是
    std::array

  • B
    已损坏。如果其实例是值初始化的,则其成员将正确初始化。它需要修复


  • 效果完全相同。欢迎来到C++世界…@ doc:对于某些类型,效果会完全一样,但是差异会导致其他类型的未定义行为。欢迎来到C++世界。@ doc:即使它是类类型,如果它不声明默认构造函数,仍然有区别。<代码> sf::CulcCeSpHe> < /Cord>类定义了默认构造函数,所以没有区别。doc做得好,您已经证明对于这种特定类型没有区别,但您上面的评论总体上仍然具有高度误导性。@tenfour:不,成员总是按照声明顺序进行初始化。@KubaOber:是的。(尽管这取决于变量的存储持续时间。如果它是静态的,那么它无论如何都是零初始化的)。@KubaOber这不是一个完全无关的细节:它让你可以选择初始化。也许您的应用程序无法让成员得到零初始化。C++给了你很多控制,这给你带来了一些痛苦/潜在的不幸。抱歉,我想添加更多的信息,而不是评论框。把这归咎于一个新手的错误。我改为编辑了原来的帖子——我希望这是正确的做法。@KubaOber我同意这一点。我还认为关于
    struct
    class
    的编码约定只会造成混乱(语言没有强制执行,各地略有不同),甚至会让人们忘记它们其实是一样的东西
    struct
    是为了与C兼容而保留的,
    class
    很可能是作为一种OO时尚而采用的。我强烈不同意任何让成员未初始化的类型都会被破坏,需要修复的说法。有很多类型,例如
    std::arra
    
    struct B
    {
      int i, j, k;
    };
    
    struct A
    {
      A() : b() {} // value-initializes b: b.i, b.j, b.k zero initialized
    
      B b;
    };
    
    struct AA
    {
      AA() {} // default-initializes b: b.i, b.j, b.k have no initialization
    
      B b;
    };