首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >评估顺序

评估顺序
EN

Stack Overflow用户
提问于 2010-12-14 19:34:51
回答 4查看 401关注 0票数 1

我想知道这样的构造(初始化列表)是否有定义好的EO (求值顺序):

代码语言:javascript
复制
struct MemoryManager
    {
        Pair* firstPair_;//<-beg
        Pair* currentPair_;
        Pair* lastPair_;//<-end

        MemoryManager():lastPair_(currentPair_ = firstPair_ = nullptr)
            {/*e.b.*/}
};

如果是,我个人更喜欢这种方式,而不是更传统的方式:

代码语言:javascript
复制
    MemoryManager():firstPair_(nullptr),
                    currentPair_(nullptr),
                    lastPair_(nullptr)
    {/*e.b*/}
EN

回答 4

Stack Overflow用户

发布于 2010-12-15 01:49:45

正如John Dibling所说,对于给定的具体示例,您的构造在技术上是正确的,但它很脆弱,对于许多程序员来说很难理解。

脆性:

如果更改了声明顺序,则

  • 可能会失败。如果更改了初始化列表,
  • 可能会失败。

要自己评估这样的构造,首先要记住这个想法:代码不是要指示编译器执行您的命令,而是要将您的意图传达给其他人(也许还有您后来的自己)。

因此,请尝试编写清晰的代码。

干杯&哈。

票数 4
EN

Stack Overflow用户

发布于 2010-12-15 06:07:25

如果你想这样做,那么就按照每个人都能理解的方式来做,而不必浏览标准:

代码语言:javascript
复制
MemoryManager()
  // no initialization here
{
  lastPair_ = currentPair_ = firstPair_ = nullptr;
}

然而,我真的看不出这能为你买到什么

代码语言:javascript
复制
MemoryManager()
  : lastPair_(), currentPair_(), firstPair_()
{}

它只需要半打左右的字符就能做同样的事情。

票数 1
EN

Stack Overflow用户

发布于 2010-12-15 03:54:17

对于此特定示例,成员的初始化顺序无关紧要。以下构造函数将具有与问题中的构造函数相同的行为:

代码语言:javascript
复制
MemoryManager():firstPair_(lastPair_ = currentPair_ = nullptr)
{/*e.b.*/}

这是因为成员是POD,所以根本不是由构造函数默认初始化的(12.6.2/4 C++ '03):

如果给定的非静态数据成员或基类不是由mem-initializer-id命名的(包括由于构造函数没有ctor-initializer而没有mem-initializer-list的情况),则

  • 如果实体是类类型(或其数组)或基类的非静态数据成员(可能是限定的cv),并且实体类是非POD类,则该实体是默认初始化的(8.5)。如果实体是常量限定类型的非静态数据成员,则实体类应具有用户声明的默认constructor.
  • Otherwise,该实体未初始化。如果实体是常量限定类型或引用类型,或者(可能是cv限定的) POD类类型(或其数组)包含(直接或间接)常量限定类型的成员,则程序的格式不正确。

对于上面的原始指针成员,“否则”项目符号适用。

现在,即使成员具有类类型,也可以这样说:

代码语言:javascript
复制
class MbrType {
public:
  MbrType();
  MbrType(int *);
  MbrType(MbrType const &);
  MbrType & operator=(MbrType const &);
};

然后,您编写的构造函数将导致成员具有您期望的值,但非优化编译器将被允许实现您的构造函数为:

代码语言:javascript
复制
MemoryManager()
: firstPair_ ()  // implicit call to default constructor
, currentPair_ () // implicit call to default constructor
, lastPair_(currentPair_.operator=(firstPair_.operator=(MbrType (nullptr))))
{/*e.b.*/}

从而导致6次调用而不是3次调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4438689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档