首页 文章

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

提问于
浏览
1

我们有两个类: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 回答

  • 3

    你可以说 Base 声明 PrintValue protected 就像是这样说:"I trust deriving classes to use this member correctly" . 因此,如果 Derived 决定公开披露它,那么只要维持 PrintValue 的所有 Contract 保证就可以了 .

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

  • 2

    If your function shouldn't be used by outside world ,把它变成 private . 如果它属于基类的内部并且您希望保留更改实现详细信息的自由,或者外部世界的调用可能会使您的对象处于不稳定状态,则特别建议这样做 .

    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 ! 
    };
    

    如果你选择使你的函数 protected ,那是因为 you want to give away the freedom to use it to its derived classes . 但是你必须接受游戏规则:通过这种自由,你也可以直接(如你所示)或通过调用受保护函数的自己的函数间接地放弃暴露它的自由 . 这两种情况都没有那么不同:最后你的基本功能可以由一个局外人触发到基类!

    从软件工程的角度来看,只要你保护一个功能,你就会把它暴露给其他用户(当然比公开曝光更受限制,但仍然比私人更暴露),你创造了对某些稳定性的期望API . 引用Scott Meyers的话说:"protected is no more encapsulated than public."

相关问题