为什么C ++继承不允许基类的公共成员继承到派生类的私有成员?

时间:2016-06-06 23:01:38

标签: c++ class inheritance

我想知道继承的事情。

class Base{
   public:
     virtual int f(){return 0;}
};
class Derived:public Base{
   private:
     virtual int f(){return 100000;}
};
int g(Base & b){
     return b.f();
}
int main(void){
     Base b;
     cout << "g(b) = " << g(b) << endl;
     Derived d;
     cout << "g(d) = " << g(d) << endl;

}

我有2个类,一个是具有虚函数f的Base类,另一个是从Base类继承的Derived类。但Derived类具有私有成员函数的虚函数f。 问题是在Base类中虚函数f是公共成员,但在派生类中虚函数f是私有成员。 当我执行这个程序时,结果是

g(b) = 0
g(d) = 100000

我认为这意味着价值基数&amp; b(在函数g中)可以控制派生的私有成员。所以这是不允许使用的。 所以我想知道为什么我们不将Base类中的公共成员重新定义为Derived类中的私有成员?

2 个答案:

答案 0 :(得分:2)

  

所以我想知道为什么我们不将Base类中的公共成员重新定义为Derived类中的私有成员?

没有技术理由禁止收紧公共父公共虚拟成员函数的覆盖的访问说明符。语言允许它。执行此操作的程序格式正确,其行为已明确定义。但是,做出这样的事情的实际原因也很少,因为父级的成员仍然可以访问,虚拟调度到达私有覆盖,如您所示。

其他语言在这个问题上做出了不同的决定。例如,Java不允许覆盖来收紧访问修饰符。

答案 1 :(得分:1)

C ++允许您覆盖publicprotectedprivate。但无论它是否会覆盖public基类函数,都可以通过该接口调用。这为C ++程序员提供了额外的控制......

使用覆盖private,您无法直接致电d.f(),这有助于防止意外/不当使用。

私有覆盖的实用程序示例

struct TCP_Client
{
    virtual void disconnect();
    ...other things...
};

struct FTP_Client : TCP_Client
{
    void quit();
    ...other things...
  private:
    void disconnect() override;
};

以上内容反映了FTP_Client TCP_Client的设计,因此TCP_Client界面可以方便地公开继承 - 这意味着您可能会获得TCP_Client收集或稍后添加的统计信息,例如#byte sent / recv-ed。但是,通过制作disconnect() private,您可以鼓励用户调用quit(),这会在调用disconnect()之前向服务器发送正确的“QUIT”消息。你可以disconnect()发送QUIT,但是说服务器没有响应,你决定在TCP级别disconnect() - 明确地转移到TCP_Client&后明确表示你是故意这样做 - 为什么还要发送QUIT:输出流缓冲区可能已满,你的应用无法排入更多数据....