14

虽然我见过需要私有继承的罕见情况,但我从未遇到需要受保护继承的情况。有人有例子吗?

4

3 回答 3

13

这里的人似乎误认为受保护的类继承和受保护的方法。

FWIW,我从未见过有人使用受保护的类继承,如果我没记错的话,我认为 Stroustrup 甚至认为“受保护”级别是 C++ 中的错误。如果您删除该保护级别并仅依赖公共和私人,那么您将无能为力。

于 2008-08-28T11:57:18.053 回答
5

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

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”函数来提供基类及其函数的受控可见性,无论出于何种原因。

但是,它会在 struct 中失败d2,因为d2不知道它d1是从base. 因此,covariance将不起作用。解决这个问题的一种方法是派生它们受保护,以便继承在 d2 中可见。

使用它的一个类似示例是当您从 派生std::ostream但不希望随机人写入您的流时。您可以提供一个getStream返回的虚函数std::ostream&。该函数可以为下一个操作准备流。例如放入某些机械手。

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

logger.getStream() << "we are padded";
于 2008-11-11T09:44:27.467 回答
1

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() {
        // ...
    }

    // ...
};

现在,如果你想从 Derived 类派生,并且你想Base::service()在派生类中使用(比如你想移动Derived::someFunction()到派生类),实现这一点的最简单方法是将私有继承更改Base为受保护继承。

抱歉,想不出更具体的例子。就个人而言,我喜欢将所有继承公开,以免浪费时间讨论“我应该使继承关系受保护还是私有”的​​讨论。

于 2008-09-17T11:36:12.413 回答