为啥 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++ 允许直接从子类中调用祖父类方法?的主要内容,如果未能解决你的问题,请参考以下文章