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++ 覆盖继承的方法的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的多重继承导致难以覆盖通用功能

C++:覆盖公共\私有继承

继承类中的c ++成员变量类型覆盖

C++ 继承 - 覆盖函数,包括使用 "::"s、.h 文件和 .cpp 文件

我可以在继承中只覆盖一种方法吗?

Java继承