C++初始化列表 - 我不明白
在Effective C++中,初始化列表中的数据元素需要按照其声明的顺序列出。进一步说,这样做的原因是数据元素的析构函数以其构造函数的相反顺序被调用。
但我只是不明白这怎么会成为一个问题......
In Effective C++, it is said that data elements in the initialization list need to be listed in the order of their declaration. It is further said that the reasoning for this is that destructors for data elements get called in the reverse order of their constructors.
But I just don't see how this could be a problem...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我们考虑以下几点:
第二个(注释掉的)构造函数看起来没问题,但实际上只有
var2
会被初始化 -var1
将首先被初始化,并且它将用 < code>var2 此时尚未初始化。如果您以与类声明中列出的成员变量相同的顺序列出初始化程序,则此类错误的风险会大大降低。
Well consider the following:
The second (commented out) constructor looks allright, but in fact only
var2
will be initialized -var1
will be initialized first and it will be initialized withvar2
that is not yet initialized at that point.If you list initializers in the same order as member variables are listed in the class declaration risk of such errors becomes much lower.
当成员也是某种以某种方式相互依赖的类的对象时,构造和销毁的顺序可能很重要。
考虑一个简单的例子:
这个例子的目的是成员
s_length
保存存储字符串的长度。但这是行不通的,因为s_length
将在s
之前初始化。所以你在执行s
的构造函数之前调用s.length
!The order of construction and destruction may be important when the members are also objects of some class that somehow depend on each other.
Consider a simple example:
The intention in this example is that member
s_length
holds the length of the stored string. This will not work however, becauses_length
will be initialised befores
. So you calls.length
before the constructor ofs
is executed!例如,如果您有一个这样的类:
类 X 的构造函数看起来像是首先初始化“b”,但实际上它是按照声明的顺序初始化的。这意味着它将首先初始化“a”。然而,“a”被初始化为“b”的值,而“b”尚未初始化,因此“a”将得到一个垃圾值。
For example if you have a class like this:
The constructor for class X looks like it initialises "b" first but it actually initialises in order of declaration. That means it will initialise "a" first. However "a" is initialised to the value of "b" which hasn't been initialised yet, so "a" will get a junk value.
破坏是构造的逆过程,因此元素以相反的顺序被破坏。
假设我们有 2 个成员,
a
和b
。b
依赖于a
,但a
不依赖于b
。当我们构造时,我们首先构造
a
,现在它存在,我们可以构造b
。当我们解构时,如果我们首先解构a
,这将是一个问题,因为b
依赖于它。但我们首先破坏b
并确保完整性。这是典型的。例如,在群论中,
fg
的逆是~g~f
(其中~f
是f
的逆) code>)穿衣服时,先穿袜子,再穿鞋。脱衣服时,先脱鞋,然后脱袜子。
Destruction is the reverse of construction, therefore elements are destructed in reverse order.
Let us say we have 2 members,
a
andb
.b
depends ona
buta
does not depend onb
.When we construct, we first construct
a
and now it exists we can constructb
. When we destruct, if we destructa
first this will be a problem asb
depends on it. But we destructb
first and integrity is ensured.This is typical. For example in group theory, the inverse of
fg
is~g~f
(where~f
is the inverse off
)When you dress, you first put on socks and then you put on shoes. When you undress you first remove the shoes, then the socks.
如果您的成员的构造函数之一抛出异常,也可能会出现问题。然后,所有已经正确构造的成员都必须按某种顺序进行析构,因为没有类似于析构函数的初始值设定项列表的东西。此顺序与类声明中成员的出现顺序相反。一个例子:
输出将是这样的:
It also could be a problem if one of the constructors of your members throws an exception. Then all members which were already properly constructed must be destructed in some order because there isn't something similar to initializer-lists for destructors. This order is the reverse order of appearance of the members in the class declaration. An example:
The output will be something like this:
请参阅 Steve Jessop 的评论 类组件初始化顺序
See Steve Jessop's comment at Class component order of initialisation