我们有两个类: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 回答
你可以说
Base
声明PrintValue
protected
就像是这样说:"I trust deriving classes to use this member correctly" . 因此,如果Derived
决定公开披露它,那么只要维持PrintValue
的所有 Contract 保证就可以了 .在良好实践方面,我强烈希望在内部调用受保护的基本方法的
Derived
中添加一个公共成员 .If your function shouldn't be used by outside world ,把它变成 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."