C++ 覆盖继承的方法
Posted
技术标签:
【中文标题】C++ 覆盖继承的方法【英文标题】:C++ override inherited methods 【发布时间】:2016-01-25 19:31:40 【问题描述】:我有以下两个课程。由于Child
继承自Father
,我认为Child::init()
会覆盖Father::init()
。为什么,当我运行程序时,我得到的是“我是父亲”而不是“我是孩子”?如何执行Child::init()
?
你可以在这里测试它:https://ideone.com/6jFCRm
#include <iostream>
using namespace std;
class Father
public:
void start ()
this->init();
;
void init ()
cout << "I'm the father" << endl;
;
;
class Child: public Father
void init ()
cout << "I'm the child" << endl;
;
;
int main (int argc, char** argv)
Child child;
child.start();
【问题讨论】:
您没有将init
函数设为虚拟(即virtual void init();
)。
因为init不是virtual
,而start
属于Father
类所以它会调用那里定义的init
。
孩子的init()
不会覆盖父亲的init()
基本上Child::start()
是Father::init()
。
我很惊讶没有给出隐藏父方法的警告:(
阴影不是值得警告的事情,因为有时这正是程序员想要的:/
【参考方案1】:
当前Child::init
是隐藏 Father::init
,而不是覆盖它。您的 init
成员函数需要为 virtual
才能获得动态调度:
virtual void init ()
cout << "I'm the father" << endl;
;
或者,您可以将 Child::init
标记为 override
以明确表示您要覆盖虚函数(需要 C++11):
void init () override
cout << "I'm the child" << endl;
;
【讨论】:
当没有虚拟时,由于没有后期绑定,因此在编译时计算为指向基类的指针,这是您的意思吗?因为如果它不是虚拟的,并且 init 是公共的,那么 child.init() 会打印 child。那么这个指针是这种行为的原因吗? “override”关键字的另一个目的是让编译器检查并确保基类和派生类中的两个方法具有相同的签名。如果派生类中的方法使用了关键字“override”,但其签名与基类中的任何方法都不匹配,则编译器会报错。【参考方案2】:你应该用函数说明符virtual
定义函数
例如
#include <iostream>
using namespace std;
class Father
public:
virtual ~Father()
void start ()
this->init();
;
virtual void init () const
cout << "I'm the father" << endl;
;
;
class Child: public Father
void init () const override
cout << "I'm the child" << endl;
;
;
int main()
Child child;
child.start();
return 0;
否则函数start
在其自身类的范围内搜索名称init
。并且因为函数init
不是虚拟的,即它没有在派生类中被覆盖,所以基类函数init 被调用。
【讨论】:
当没有 virtual 时,由于没有后期绑定,因此在编译时计算为指向基类的指针,这是您的意思吗?【参考方案3】:如果你想让孩子重写init方法,你必须在基类virtual
中创建init
方法。
class Father
public:
void start ()
this->init();
;
virtual void init ()
cout << "I'm the father" << endl;
;
;
重新声明和重新实现其基础之一的虚拟方法的类被称为覆盖该方法。为了对方法进行后期绑定,您需要声明该方法virtual
。
【讨论】:
以上是关于C++ 覆盖继承的方法的主要内容,如果未能解决你的问题,请参考以下文章