初始化列表 - 我可以使用同一类的其他成员初始化成员吗?

时间:2014-06-05 22:28:15

标签: c++

为了RAII,我希望将我的类成员保留为值对象,但我也希望将指向其他对象的指针传递给它们的构造函数,以确保它们立即初始化。

我使用构造函数初始化列表初始化它们,但我不确定是否可以使用指向其他类成员的指针初始化类成员。

以下代码使用Apple LLVM 5.1编译器在XCode中按预期编译和工作,但这是我可以使用并信任所有编译器的定义行为吗?而且,这是一般的好习惯还是要避免的事情?除了init()函数之外,还有其他方法可以实现吗?

class Foo {
public:
    int value;
    Foo() {}
    void woot() {
        std::cout << "A Foo says WOOT my value is: " << value << std::endl;
    }
};

class Bar {
public:
    Foo* foo;
    int value;
    Bar( Foo* f ) : foo(f) {
        foo->value = 66;
        foo->woot();
    }
    void woot() {
        std::cout << "A Bar says WOOT my value is:  " << value << std::endl;
    }
};

class Boo {
public:
    Foo* foo;
    Bar* bar;
    int value;
    // Passing members into constructors of other members:
    Boo( Foo* f, Bar* b ) : foo(f), bar(b) {
        foo->value = 77;
        foo->woot();
        bar->value = 88;
        bar->woot();
    }
};

class Yaa {
public:
    Foo foo;
    Bar bar;
    Boo boo;
    Yaa() : bar(&foo), boo(&foo, &bar) {
        woot();
    }
    void woot() {
        std::cout << "A Yaa says WOOT, my children say woot:" << std::endl;
        foo.woot();
        bar.woot();
    }
};

void testInitialisation() {
    Yaa f;
}

// ...

testInitialisation();

// Output:
// A Foo says WOOT my value is: 66
// A Foo says WOOT my value is: 77
// A Bar says WOOT my value is:  88
// A Yaa says WOOT, my children say woot:
// A Foo says WOOT my value is: 77
// A Bar says WOOT my value is:  88

编辑/注意:在接受@Wes Hardaker的回答之后,我接受了他的建议,并对初始化顺序做了一些阅读。我相信在阅读&#34;最佳实践&#34;注意&#34; C ++ Primer&#34;,[Lippman,Lajoie,&amp; Moo]:

  

......如果可能,请避免使用成员初始化其他成员。

后来,我心里想到这个想法是错的,但在再次阅读本章之后我才意识到这是完全合法的,尽管应该谨慎使用。该书实际上警告了使用成员初始化其他成员时可能存在的危险。 初始化的顺序取决于成员在类中声明的顺序,而不是它们在初始化列表中的顺序。这意味着如果您向后收到订单,则可能会将未定义的成员传递给另一个成员。

如果你小心的话,那很好,但我想它可能会在以后再回来咬你(或其他人使用你的代码)。

1 个答案:

答案 0 :(得分:1)

是的,这是合法的并且在很多地方使用。如果您查看C ++参考文本,您会发现它涉及初始化排序,您可以放心自己这是真的。