C++继承的引用成员在构造函数中的默认初始化

3
我有一个基类更新外部引用,我想要建立一个继承的类将这个引用嵌入成员中。一种引用的默认初始化方式。
我提出了以下解决方案:
#include<iostream>

class Statefull
{
public:
    Statefull( int& ref ) : _base_ref(ref) {}
    int& _base_ref;
    // update the extern variable
    void work() { std::cout << ++_base_ref << std::endl; }
};

class Stateless : public Statefull
{
public:
    // use a temporary allocation
    Stateless( int* p = new int() ) :
        // we cannot initialize local members before base class:
        // _dummy(), Statefull(_dummy)
        // thus, initialize the base class on a ref to the temporary variable
        Statefull(*p),
        _tmp(p),
        _dummy()
    {
        // redirect the ref toward the local member
        this->_base_ref = _dummy;
    }
    int* _tmp;
    int _dummy;
    // do not forget to delete the temporary
    ~Stateless() { delete _tmp; }
};

int main()
{
    int i = 0;
    Statefull full(i);
    full.work();

    Stateless less;
    less.work();
}

但是,在构造函数的默认参数中需要一个临时分配似乎很丑陋。是否有更优雅的方法来实现这种默认初始化,同时在基类构造函数中保留引用


1
你不需要“重定向”引用。你只是为 _base_ref 引用的变量赋值,这个值来自 dummy。你不能重定向引用,只能对其进行初始化。 - fork0
继承层次结构是否合理?我期望要么Stateless是基类,要么有第三个类作为公共基类。 - Simon Richter
@SimonRichter,问题在于_ref_base的声明,在Stateless中它不应该是一个引用,在Statefull中它是。如果我不想重新实现work,那么就需要在基类中将_ref_base声明为模板,但我更愿意避免这样做。 - nojhan
3个回答

4

好的,Stateless类违反了三大法则。但我假设这只是展示真正问题的示例代码。

现在,为了实际解决问题:只要在初始化实际发生之前不使用其值,就可以将引用绑定到未初始化的变量上。

Stateless() : Statefull(_dummy), _dummy() {}

目前的解决方案可以运行,但似乎对于为什么它可以运行存在一些误解。

    // redirect the ref toward the local member
    this->_base_ref = _dummy;

您不能“重定向”引用。您只能在初始化时绑定一次引用。将引用分配给对象。在这种情况下,this->_base_ref = _dummy *_tmp = _dummy 完全相同:它将_dummy的值分配给*_tmp。然而,_base_ref仍然引用*_tmp(您可以使用assert(&_base_ref == tmp)进行测试)。

只要在初始化实际发生之前没有使用它的值。 确实如此。这在我的真实世界示例中会非常令人恼火... - nojhan

1

我认为这可能有效:

StateLess(): Statefull(*new int) {}
~StateLess() { delete &_base_ref; }

你不能没有临时变量,但它们不必在类定义中。


0

一切都可以通过使用更多的类来解决

class StateForStateful
{
protected:
    int state;
};

class Stateless: private StateForStateful, public Stateful // order is important
{
public:
     Stateless():Stateful(this->state) {}
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接