成员变量可以用于初始化初始化列表中的其他成员吗? [英] Can member variables be used to initialize other members in an initialization list?

查看:213
本文介绍了成员变量可以用于初始化初始化列表中的其他成员吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下(简化)情况:

  class Foo 
{
private:
int evenA;
int evenB;
int evenSum;
public:
Foo(int a,int b):evenA(a-(a%2)),evenB(b-(b%2)),evenSum(evenA + evenB)
{
}
};

当我现在这样做时:

  Foo foo(1,3); 

那么evenA是0,evenB是2,但是evenSum会初始化为2?



我在我当前的平台(iOS)上试过,似乎工作,但我不知道这个代码是否可移植。


$ b $

感谢您的帮助!

解决方案



成员按照在类体中声明的顺序初始化,而不是按顺序初始化列在初始化列表中。所以如果你改变类体,这段代码可能会默默失败(虽然很多编译器会发现这个并发出警告)。





1。从C ++标准中的[class.base.init]:


在非委托构造函数中,初始化过程如下顺序:




  • 首先,只有最衍生类的构造函数(1.8),虚拟基类才在
    它们在基类的有向无环图的深度优先从左到右遍历中出现的顺序
    其中从左到右是派生类基类中的基类的出现顺序-specifier-list。

  • 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list
    中(不管mem- )。

  • 然后,非静态数据成员按照在类定义中声明的顺序进行初始化




<

(突出显示是我的)



标准的这一部分接着举一个使用成员变量初始化其他成员变量。


Consider the following (simplified) situation:

class Foo
{
private:
    int evenA;
    int evenB;
    int evenSum;
public:
    Foo(int a, int b) : evenA(a-(a%2)), evenB(b-(b%2)), evenSum(evenA+evenB)
    {
    }
};

When i instanciate Foo like this:

Foo foo(1,3);

then evenA is 0, evenB is 2, but will evenSum be initialized to 2?

I tried this on my current platform (iOS) and it seems to work, but I'm not sure whether this code is portable.

Thanks for your help!

解决方案

This is well-defined and portable,1 but it's potentially error-prone.

Members are initialized in the order they're declared in the class body, not the order they're listed in the initialization list. So if you change the class body, this code may silently fail (although many compilers will spot this and emit a warning).


1. From [class.base.init] in the C++ standard(s):

In a non-delegating constructor, initialization proceeds in the following order:

  • First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where "left-to-right" is the order of appearance of the base classes in the derived class base-specifier-list.
  • Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
  • Finally, the compound-statement of the constructor body is executed.

(Highlighting is mine.)

This section of the standard then goes on to give an example of using member variables to initialize other member variables.

这篇关于成员变量可以用于初始化初始化列表中的其他成员吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆