为啥 c++ 允许直接从子类中调用祖父类方法?

Posted

技术标签:

【中文标题】为啥 c++ 允许直接从子类中调用祖父类方法?【英文标题】:Why c++ allows to call grandparent class method directly from within child class?为什么 c++ 允许直接从子类中调用祖父类方法? 【发布时间】:2015-03-06 16:51:21 【问题描述】:

为什么 C++ 允许直接从子类中调用祖父类方法。这不违反封装吗?像 Java 这样的语言不允许绕过父类方法意味着 super.super.method() 是不允许的。但它在 C++ 中有效。是什么原因?考虑以下代码。

#include <iostream>
class a1 

  public:
  void fun()
 
    std::cout<<"fun() in a1\n";
 
;

class a2 : public a1

   public:
   void fun() 
   
       std::cout<<"fun() in a2\n";
   
;

class a3 : public a2

   public:
   void fun()        // Bypass call to a2 class' method
   
       a1::fun();
       std::cout<<"fun() in a3\n";
   
;

int main()

     a3 a;
     a.fun();
     return 0;

【问题讨论】:

因为 c++ 不在乎你是否在脚上开枪 :) a1::fun()a2::fun()a3::fun() 是三个独立的函数,因为前两个函数都没有声明为 virtual。所以不要认为每个派生类都覆盖了之前的函数。您可以随意调用任何您想要的继承函数,这通常非常有用。 考虑组合而不是继承,或者私有/受保护的继承 为什么会被禁止?这是一种公共方法。您甚至可以通过基类指针从外部调用它(缺少 virtual 关键字?) @Cyber​​:那为什么 Java 不允许这样做? 【参考方案1】:

你问:

这不违反封装吗?

在一定程度上确实如此。理想情况下,如果a3 需要访问其祖先类的任何功能,它应该通过其直接基类,即父类。如果设计更改并且a2 不再从a1 派生,a3::fun 中的代码将中断。

你问:

是什么原因?

很可能有很长的原因列表,太长而无法放入 SO 答案中。我怀疑主要原因是允许程序员灵活地做对他们有意义的事情。

【讨论】:

@R Sahu:谢谢你的回答我很满意。但是,如果设计更改并且 a2 不再从 a1 派生,那么 a3::fun 中的代码将中断是什么意思?谢谢 @meet,在程序的生命周期中,有时需要重新组织类层次结构。在将来的某个日期,将a2 设为foo 的子类可能是有意义的,它不是从a1 派生的。当时a1不是a3的祖类。因此,您不能从a3::fun() 调用a1::fun()【参考方案2】:

Python 有一个基本范式:“我们都是受过教育的成年人”。换句话说:语言的设计者明白某些特性可能会被滥用;但他们依靠程序员的理智来小心。

在我看来,这与 C++ 非常相似;它只是不像 python 那样是“官方口头禅”。

【讨论】:

以上是关于为啥 c++ 允许直接从子类中调用祖父类方法?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi子类调用祖父类的虚函数

为啥继承在 Java 和 C++ 中的行为不同,超类调用(或不调用)子类的方法?

子类为啥不能直接调用父类的属性

子类可以直接调用父类的函数吗

子类为啥要调用父类的构造函数

Object在其子类中,为啥不能调用clone()???