将类成员传递给基类构造函数(通过引用)

Sam*_*uca 9 c++

给出以下类ConcreteBar实现BarIfc:

class Base {

public:

    Base(BarIfc& bar) : _bar(bar) { }

    void foo() {
        _bar.bar();
    }

private:

    Base(const Base& other);
    Base& operator=(const Base& other);

    BarIfc& _bar; // Pure virtual interface
};

class Child : public Base {

public:
    // bar is passed to base class before initialization
    Child(int i) : Base(_bar), _bar(i) { 
    }

private:

    Child(const Child& other);
    Child& operator=(const Child& other);

    ConcreteBar _bar;
};
Run Code Online (Sandbox Code Playgroud)

我是否正确地假设这一点

Child(int i) : Base(_bar), _bar(i) {}
Run Code Online (Sandbox Code Playgroud)

只要我不在_bar基类的初始化列表中使用(例如调用方法)引用,它就是"有效"的C++ ?

Mar*_* A. 10

假设ConcreteBar是一个子对象

它是有效的,因为存储已分配给§3.7.5/ 1

成员子对象,基类子对象和数组元素的存储持续时间是其完整对象的存储持续时间(1.8).

和§3.8/ 5说:

在对象的生命周期开始之前但是在对象将占用的存储之后,或者在对象的生命周期结束之后以及在重用或释放对象占用的存储之前,任何指向存储的指针之前可以使用对象将位于或位于的位置,但仅限于有限的方式.对于正在建造或销毁的物体,见12.7 [指非静态成员用法]

这样只要你不使用引用就有效.


Joh*_*nck 7

是的,它是有效的,因为虽然_bar还没有构建,但它的存储确实存在,并且只要你实际上没有使用该引用,直到你在派生类构造函数体中,它才能引用它.

这是关于类似主题的另一篇文章,你可能会发现它很有启发性:https://stackoverflow.com/a/5905746/4323

最后,引用标准的答案:https://stackoverflow.com/a/6258431/4323说:

在对象的生命周期开始之前但在对象占用的存储空间被分配之后[...],可以使用任何指向对象所在或存在的存储位置的指针,但只能以有限的方式使用.