评估顺序
我想知道像这样的构造(初始化列表)是否具有明确定义的 EO(评估顺序):
struct MemoryManager
{
Pair* firstPair_;//<-beg
Pair* currentPair_;
Pair* lastPair_;//<-end
MemoryManager():lastPair_(currentPair_ = firstPair_ = nullptr)
{/*e.b.*/}
};
如果是,我个人更喜欢这种方式而不是更传统的方式:
MemoryManager():firstPair_(nullptr),
currentPair_(nullptr),
lastPair_(nullptr)
{/*e.b*/}
I wonder if construction like this (initialization list) has well defined EO (evaluation order):
struct MemoryManager
{
Pair* firstPair_;//<-beg
Pair* currentPair_;
Pair* lastPair_;//<-end
MemoryManager():lastPair_(currentPair_ = firstPair_ = nullptr)
{/*e.b.*/}
};
If yes I personally would prefer this way to the more conventional:
MemoryManager():firstPair_(nullptr),
currentPair_(nullptr),
lastPair_(nullptr)
{/*e.b*/}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如 John Dibling 所说,对于给定的具体示例,您的构造在技术上是正确的,但是它很脆弱,对于很多程序员来说很难理解。
脆弱性:
如果更改声明顺序可能会失败。
如果初始化列表发生更改,可能会失败。
要自行评估此类构造,请首先牢记以下想法:代码并不是要指示编译器执行您的命令;而是要让编译器执行您的命令。这是关于将您的意图传达给他人(也许还有您后来的自己)。
因此,尝试编写清晰代码。
As John Dibling has remarked, your construct is technically correct for the given concrete example, but it's brittle and it's hard to understand for many programmers.
Brittleness:
Can fail if the order of declaration is changed.
Can fail if the init list is changed.
To evaluate such constructs on your own, keep this idea foremost in your mind: code is not about instructing the compiler to do your bidding; it is about communicating your intent to others (and perhaps your later self).
Hence, try to write clear code.
是。如代码所示,成员将按照它们在结构/类定义中声明的顺序进行初始化(构造函数定义中初始化程序的顺序无关紧要,最多您会收到警告告诉你它们的顺序不正确)。
然而,更传统的方式有一个存在的理由,即如果变量声明的顺序发生变化(例如,由于重构),代码不会默默地中断。人们不会轻易认为声明的顺序是相关的,除非警告另有说明。
Yes. As shown in your code, the members will be initialized in the same order they are declared in the struct/class definition (the order of initializers in the constructor definition is irrelevant, at best you will get a warning telling you they are in an incorrect order).
However, the more conventional way has a reason to exist, namely that if the order of declaration of the variables changes (for instance, due to refactoring), the code will not break silently. People don't readily assume the order of declaration is relevant, unless a warning tells them otherwise.
如果你想这样做,那就按照每个人都能立即理解的方式去做,而不必浏览标准:
但是,我真的不明白这会给你带来什么
,因为它只用了大约六个字符就完成了完全相同的工作。
If you want to do this, then do it the way everybody understands immediately without having to browse the standard:
However, I don't really see what this buys you over
which does exactly the same in only about half a dozen more characters.
对于这个特定示例,成员的初始化顺序无关紧要。以下构造函数将具有与问题中的构造函数相同的行为:
这是因为成员是 POD 等根本不由构造函数默认初始化 (12.6.2/4 C++ '03):
对于上面的原始指针成员,“否则”项目符号适用。
现在,即使成员确实具有类类型,例如:
然后,您编写的构造函数将导致成员具有您期望的值,但将允许非优化编译器将您的构造函数实现为
:调用 6 次而不是 3 次。
For this specific example, the initialization order for members is irrelevant. The following constructor would have the same behaviour as the one in the question:
This is because the members are POD and so are not default initialized by the constructor at all (12.6.2/4 C++ '03):
For the raw pointer members above, the 'otherwise' bullet applies.
Now, even if the members did have class type, say:
Then, the constructor as you've written it would result in the members having the values that you expect, but a non optimizing compiler would be allowed to implement your constructor as:
Resulting in 6 calls rather than 3.
不,但这并不重要。您的代码不依赖于
currentPair_
和firstPair_
归零的顺序。No, but it doesn't matter. Your code does not depend on the order in which
currentPair_
andfirstPair_
are zeroed.