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

Why C++ inheritance not allow base class's public member inherit to derived class's private member?

本文关键字:继承 成员 派生 C++ 不允许 基类 为什么      更新时间:2023-10-16

我想知道一些关于继承的事情。

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;

}

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

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

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

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

没有任何技术理由禁止收紧公共父级的公共虚拟成员函数的覆盖的访问说明符。语言允许这样做。这样做的程序是格式良好的,其行为也是定义良好的。然而,也很少有实际的理由去做这样的事情,因为父成员仍然可以访问,并且虚拟调度到达私有覆盖,正如您所展示的那样。

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

C++允许您重写publicprotectedprivate。但不管怎样,它将覆盖CCD_ 4基类函数并且可以通过该接口被调用。这为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:输出流缓冲区可能已满,你的应用程序无法将更多数据排队。。。。