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

C++ default initialization in constructor of an inherited reference member

本文关键字:C++ 默认 初始化 构造函数 引用 成员 继承      更新时间:2023-10-16

我有一个更新外部引用的基类,我想构建一个继承类,将此引用作为成员嵌入。引用的一种默认初始化。

我想出了以下解决方案:

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

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

好吧,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)来测试这一点)。

我认为这可能有效:

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

你不能没有临时性,但它们不一定在类定义中。

使用更多的类可以解决所有问题

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