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();
}

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

4

3 回答 3

4

好吧,Stateless班级违反了三人规则。但我认为这是因为这只是展示真正问题的示例代码。

现在,要实际解决这个问题:将引用绑定到未初始化的变量是完全有效的,只要在初始化实际发生之前不使用它的值。

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

目前的解决方案有效,但似乎对它为什么有效存在一些误解。

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

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

于 2012-07-18T08:40:04.207 回答
1

我认为这可能有效:

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

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

于 2012-07-18T08:46:17.270 回答
0

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

class StateForStateful
{
protected:
    int state;
};

class Stateless: private StateForStateful, public Stateful // order is important
{
public:
     Stateless():Stateful(this->state) {}
};
于 2012-07-18T10:16:23.820 回答