2010-05-04 124 views
2

我用初始化程序列表遇到以下几个问题,我从来没有能够很好地解释它。任何人都可以解释为什么完全以下失败(我没有编译器捕捉错别字,所以大家多多包涵):在构造函数初始化程序中使用成员的成员函数

class Foo 
{ 
public: 
    Foo(int i) : m_i(i) {} //works with no problem 

    int getInt() {return m_i;} 

    ~Foo() {} 
private: 
    int m_i; 
}; 

class Bar 
{ 
public: 
    Bar() : 
    m_foo(5),   //this is ok 
    m_myInt(m_foo.getInt()) //runtime error, seg 11 
    {} 

    ~Bar() {} 
private: 
     Foo m_foo; 
    int m_myInt; 


}; 

当试图调用成员的成员函数初始化上涨初始化列表中,我得到seg故障。我似乎记得这是一个已知的问题(或者可能是某种设计方式),但我从来没有见过这么好的描述。附带的例子是用普通的旧数据类型设计的,但用另一个缺少默认(空)构造函数的对象代替Bar::m_myInt,问题更加真实。任何人都可以启发我吗?

+1

Typo:'〜Foo {}'for'〜Foo(){}'? – 2010-05-04 20:32:55

+0

这个编译和运行使用GCC 3.4.3在Cygwin中没有错误。你使用什么编译器? – andand 2010-05-04 20:45:27

回答

9

初始化的顺序与初始化列表中元素的顺序无关。实际顺序是类定义中成员的顺序。也就是说,在你的例子中,m_foo将在m_myInt之前被初始化,不是因为初始化列表,而是因为该成员首先出现在类中。

您发布的具体示例应该可以顺利编译并运行。

+2

在gcc的情况下,你可以通过'-Wreorder',它会发出警告,如果你搞砸 – 2010-05-04 20:33:09

+0

是这是什么让我咬!我把它切换到了我的脑海。我认为初始化顺序是基于初始化列表顺序而不是类定义顺序。感谢您解决这个问题! – awm129 2010-05-05 14:08:57

3

数据成员按照类声明(示例中的private:下的顺序)中列出的顺序进行初始化。初始化程序列表中给出的顺序不受建筑顺序的限制。

所以,在你的榜样,重新排序,像这样的数据成员可能会导致未定义的行为:

private: 
    int m_myInt; 
    Foo m_foo; 

是否有可能在数据成员的顺序是不同的实际比你出?

+0

是的,我的例子应该有翻译的私人成员来充分说明问题。谢谢你的帮助! – awm129 2010-05-05 14:10:07

相关问题