简体   繁体   English

C ++使用派生类的对象访问基类的受保护成员函数

[英]C++ accessing protected member function of Base class with an object of Derived class

we have two classes: Base and Derived. 我们有两个类:基础类和派生类。 There is a function in Base class called PrintValue() which has been defined as protected. 在基类中有一个称为PrintValue()的函数已被定义为受保护。 Derived class inherits this function from Base class, but it is able to change its access specifier to public by declaring it in the public section. 派生类从基类继承此函数,但是它可以通过在公共部分声明它来将其访问说明符更改为公共。 My question is: Is this a good software engineering practice? 我的问题是:这是一种好的软件工程实践吗? why is Derived class, which inherits a function from Base class, able to change the access level of that function to public, which has already been declared as protected by Base class. 为什么是派生类,该派生类从基类继承了一个函数,可以将该函数的访问级别更改为公共,而该访问级别已被公共类声明为受保护的。 this way, in the main function you can declare an object of Derived class and access the protected function of Base class and this is against the expectation of Base class. 这样,在主函数中,您可以声明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;
}

You can argue that Base declaring PrintValue protected is like saying: "I trust deriving classes to use this member correctly". 您可以说Base声明PrintValue protected就像说:“我相信派生类可以正确使用此成员”。 So if Derived decides to expose it publicly, it is fine provided all contractual guarantees for PrintValue are maintained. 因此,如果Derived决定公开公开它,则可以保留PrintValue所有合同保证。

In terms of good practice, I would strongly prefer adding a public member to Derived that internally calls the protected base method. 根据良好实践,我强烈希望在Derived中添加一个公共成员,该成员内部调用受保护的基本方法。

If your function shouldn't be used by outside world , make it private . 如果您的功能不应被外界使用 ,请将它设为 私有 This is especially recommended, if it belongs to the internals of your base class and you want to keep freedom to change implementation details, or if a call by outside world could put your object in an unstable state. 如果它属于基类的内部,并且您想保留更改实现细节的自由,或者外界的调用可能使您的对象处于不稳定状态,则特别推荐这样做。

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

If you've chosen to make your function protected , it's because you want to give away the freedom to use it to its derived classes . 如果您选择使函数受到保护 ,那是因为您想放弃对它的派生类使用它的自由 But you must accept the rules of the game: with this freedom, you also give away the freedom to expose it, either directly (as you showed) or indirectly through an own function that calls the protected function. 但是,您必须接受游戏规则:有了这种自由,您还可以直接(如您所显示的)或通过调用受保护函数的自身函数间接释放公开它的自由。 Both cases aren't so different by the way: in the end your base function can be triggered by an outsider to the base class ! 两种情况并没有什么不同:最后,您的基函数可以由基类的局外人触发!

From a software engineering point of view, as soon as you make a function protected, you expose it to other users (of course much more limited than public exposure, but still much more exposed than private), and you create expectation about some stability of the API. 从软件工程的角度来看,一旦您将功能设置为受保护,就将其公开给其他用户(当然,其公开程度要比公共公开程度要大得多,但比私有公开程度要多得多),并且您会对功能的稳定性产生期望。 API。 So to quote Scott Meyers: "protected is no more encapsulated than public." 因此,引用斯科特·迈耶斯(Scott Meyers)的话: “受保护的范围不比公共范围的多。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM