C++ I';我对这个C+感到困惑+;建造师
我试图寻找一个答案,但不确定确切地说,最好的术语来描述这个 我正在读一本关于SFML编程的书,其中一个例子让我对构造函数的用法感到困惑 假设我们有类A和类B。类A有一个类型为B(memberB)的成员变量。的构造函数如下所示:C++ I';我对这个C+感到困惑+;建造师,c++,constructor,C++,Constructor,我试图寻找一个答案,但不确定确切地说,最好的术语来描述这个 我正在读一本关于SFML编程的书,其中一个例子让我对构造函数的用法感到困惑 假设我们有类A和类B。类A有一个类型为B(memberB)的成员变量。的构造函数如下所示: A::A() : OtherMemberType(with, params), memberB() {...} 假设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
是PODB
是一个模板参数。在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;
};