C ++使用Derived类的对象访问Base类的受保护成员函数

时间:2014-09-04 17:09:37

标签: c++ function inheritance

我们有两个类:Base和Derived。 Base类中有一个名为PrintValue()的函数,它已被定义为protected。派生类从Base类继承此函数,但它可以通过在公共部分中声明它来将其访问说明符更改为public。我的问题是:这是一个很好的软件工程实践吗?为什么Derived类从Base类继承了一个函数,能够将该函数的访问级别更改为public,该类已经被声明为Base类保护。这样,在main函数中,您可以声明Derived类的对象并访问Base类的受保护函数,这违背了Base类的期望。

class Base
{
private:
    int m_nValue;

public:
    Base(int nValue)
        : m_nValue(nValue)
    {
    }

protected:
    void PrintValue() { cout << m_nValue; }
};

class Derived: public Base
{
public:
    Derived(int nValue)
        : Base(nValue)
    {
    }

    // Base::PrintValue was inherited as protected, so the public has no access
    // But we're changing it to public by declaring it in the public section
    Base::PrintValue;
};

int main()
{
    Derived cDerived(7);

    // PrintValue is public in Derived, so this is okay
    cDerived.PrintValue(); // prints 7
    return 0;
}

2 个答案:

答案 0 :(得分:3)

您可以争辩Base声明PrintValue protected就像在说:&#34;我相信派生类正确使用此成员&#34;。因此,如果Derived决定公开公开,那么只要保留PrintValue的所有合同保证,就可以了。

在良好实践方面,我强烈希望将公共成员添加到内部调用受保护的基本方法的Derived

答案 1 :(得分:2)

如果您的功能不应被外界使用,请将其设为私有。如果它属于基类的内部并且您希望保留更改实现详细信息的自由,或者外部世界的调用可能会使您的对象处于不稳定状态,则特别建议这样做。

class Base {
...
private:   // <====   HIDE DETAILS YOU DO NOT WANT TO EXPOSE 
    void PrintValue() { std::cout << m_nValue; }
};
class Derived : public Base {
...
    Base::PrintValue;   // <===NOW IT CAN'T COMPILE BECAUSE ACCESS IS PRIVATE ! 
};

如果您已选择使您的功能受保护,那是因为您想放弃将其用于其派生类的自由 。但是你必须接受游戏规则:通过这种自由,你也可以直接(如你所示)或通过调用受保护函数的自己的函数间接地放弃暴露它的自由。这两种情况都不是那么不同:最后你的基本功能可以由一个局外人触发到基类!

从软件工程的角度来看,只要你保护一个功能,你就会把它暴露给其他用户(当然比公开曝光更受限制,但仍然比私人曝光更多),你创造了对它的期望API的一些稳定性。所以引用斯科特迈耶斯:&#34;受保护不再是公共封装。&#34;