在C ++中是否有需要"保护"继承的示例?

时间:2020-03-05 18:44:16  来源:igfitidea点击:

尽管我见过很少需要私有继承的情况,但我从未遇到过需要保护继承的情况。有人有例子吗?

解决方案

回答

这里的人们似乎误解了Protected类的继承和Protected方法。

FWIW,我从未见过有人使用受保护的类继承,如果我没记错的话,我认为Stroustrup甚至认为"受保护"级别是c ++中的错误。如果我们取消该保护级别,而仅依靠公共和私有,则几乎没有什么可以做的。

回答

C ++ FAQ Lite提到了使用私有继承是一个合理的解决方案的情况(请参阅[24.3. ]我更喜欢哪一种:组合还是私有继承?)。在这种情况下,我们想通过虚拟函数(在本例中为derivedFunction())在私有基类中调用派生类:

class SomeImplementationClass
{
protected:
    void service() {
        derivedFunction();
    }

    virtual void derivedFunction() = 0;      

    // virtual destructor etc
};

class Derived : private SomeImplementationClass
{
    void someFunction() {
        service();
    }

    virtual void derivedFunction() {
        // ...
    }

    // ...
};

现在,如果我们想从派生类中派生,并且想在派生类中使用Base :: service()(例如,我们想将'Derived :: someFunction()`移到派生类中),实现此目的最简单的方法是将" Base"的私有继承更改为受保护的继承。

抱歉,想不出更具体的例子。我个人希望公开所有继承,以免浪费时间进行"我应该使继承关系受到保护还是私有"讨论。

回答

有一个非常罕见的保护继承用例。这是我们要使用协方差的地方:

struct base { 
    virtual ~base() {} 
    virtual base & getBase() = 0;
}; 

struct d1 : private /* protected */ base { 
    virtual base & getBase() { 
        return this; 
    } 
}; 

struct d2 : private /* protected */ d1 {
    virtual d1 & getBase () { 
        return this; 
    } 
};

之前的代码段试图隐藏其基类,并通过提供" getBase"功能,出于任何原因提供了基类及其功能的受控可见性。

但是,它将在结构d2中失败,因为d2不知道d1是从base派生的。因此,"协方差"将不起作用。摆脱这种情况的一种方法是对其进行保护,以使继承在d2中可见。

一个类似的例子是当你从std :: ostream派生而又不想让随机的人写到你的流中时。我们可以提供一个虚拟的getStream函数,该函数返回std :: ostream&。该功能可以为下一个操作做一些流准备。例如,放入某些操纵器。

std::ostream& d2::getStream() {
    this->width(10);
    return *this;
}

logger.getStream() << "we are padded";