【问题标题】: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 不允许这样做?

标签: java c++ inheritance


【解决方案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 那样是“官方口头禅”。

【讨论】:

    猜你喜欢
    • 2016-02-14
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2021-08-24
    • 2017-11-09
    • 2012-02-22
    • 2012-01-21
    • 1970-01-01
    相关资源
    最近更新 更多