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

问题描述:

我有一个更新外部引用的基类,我想构建一个将此引用作为成员嵌入的继承类。一种参考的默认初始化。在继承引用成员的构造函数中的C++默认初始化

我想出了以下解决方案:

#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

你不_redirect_参考来解决。您刚刚分配了由_base_ref引用的变量,这是来自dummy的值。你不能重定向引用,只能初始化它们。 – fork0 2012-07-18 08:43:15

+0

继承层次是否有意义?我期望无状态是基类,还是第三类作为共同基础。 – 2012-07-18 08:58:02

+0

@SimonRichter问题将是'_ref_base'的声明,在'Stateless'中它不应该是一个引用,在'Statefull'中,它是。如果我不想重新实现'work',那么就需要在基类中声明'_ref_base'作为模板,我宁愿避免这种情况。 – nojhan 2012-07-18 09:21:21

我想这可能工作:

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

你离不开的临时做的,但他们没有要在类的定义。

那么,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)来测试)。

+0

“只要它的值在初始化之前没有被使用实际发生” 确实。这在我现实世界的例子中会非常恼人...... – nojhan 2012-07-18 18:35:54

一切都可以使用一些更多的类

class StateForStateful 
{ 
protected: 
    int state; 
}; 

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