C++ accessing protected member function of Base class with an object of Derived class
我们有两个类:基类和派生类。基类中有一个名为printValue()的函数已定义为protected。派生类从基类继承此函数,但它可以通过在public节中声明来将其访问说明符更改为public。我的问题是:这是一个好的软件工程实践吗?为什么派生类(它从基类继承了一个函数)能够将该函数的访问级别更改为public,而public已经声明为受基类保护。这样,在主函数中,您可以声明派生类的对象并访问基类的保护函数,这与基类的期望相反。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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; } |
你可以说,
在良好的实践中,我强烈希望在内部调用受保护基方法的
如果外部世界不应该使用您的功能,请将其设为私有。如果它属于您的基类的内部,并且您希望保持更改实现细节的自由,或者外部世界的调用可能会使您的对象处于不稳定状态,则特别建议这样做。
1 2 3 4 5 6 7 8 9 | 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稳定性的期望。所以引用斯科特·迈耶斯的话:"受保护的不比公共的更封闭。"