c ++使基类在子类中使用覆盖的方法

Posted

技术标签:

【中文标题】c ++使基类在子类中使用覆盖的方法【英文标题】:c++ make the base class use overridden methods in the child class 【发布时间】:2012-05-15 15:59:35 【问题描述】:

我正在尝试覆盖基类中另一个方法使用的基类方法;但是,当派生类调用基类的 using 方法时,派生的 used-method 永远不会执行,而是调用基类的 used-method。这是一个例子:

#include <iostream>
using namespace std;
class Base 
public:
    Base() 
    virtual ~Base() 
    void printLeft()  cout << this->getLeft(); 
    int getLeft()  return 0; 
;

class Derived: public Base 
public:
    Derived() 
    virtual ~Derived() 
    int getLeft()  return 1; 
;
int main(int argc, char *argv[]) 
    Derived d = Derived();
    d.printLeft();

运行main() 打印0,表明使用了BasegetLeft() 方法,而不是派生对象的方法。

如何更改此代码,以便在 从 Derived 实例调用时调用 Derived::getLeft()

【问题讨论】:

对不起,我没有时间。这个项目明天到期。不过,感谢您的有益建议。 对于投反对票的人,这个问题有什么特别错误的吗?我应该澄清一些事情吗?我尝试进行研究,但由于我不知道我试图描述的现象的术语,我无法找到任何相关的结果。 我对这个问题投了反对票,但直到你告诉我你不愿意读一本书来学习 C++,我才这样做。 明白了。我担心反对票可能在某种程度上是相关的。很高兴知道这只是个人的。谢谢你的诚实。 It's not personal。你不能通过阅读在线教程来很好地学习 C++。试图走捷径和吃勺子对你的同事、你的雇主、你的老师或你自己没有任何好处。 【参考方案1】:

您只需要将getLeft 设为虚拟:

class Base 
public:
    Base() 
    virtual ~Base() 
    void printLeft()  cout << this->getLeft(); 
    virtual int getLeft()  return 0; 
;

默认情况下,在 C++ 中,成员函数不是虚拟的。也就是说,您不能在子类中覆盖它们。

【讨论】:

嗯,你可以覆盖它们,只是覆盖在通过基类指针或引用调用时不会有任何效果。【参考方案2】:

对于非虚函数,使用对象的静态类型来决定调用哪个类的方法。

在您的情况下,您从Base::printLeft() 调用getLeft()this的类型是Base*,所以调用的函数就是Base::getLeft()

解决方法是使用virtual 关键字。在这种情况下,将使用虚函数表来确定要调用哪个版本的getLeft(),在这种情况下为Derived.

您可以通过在BaseDerivedprintLeft 声明前添加virtual 来触发此行为。

【讨论】:

以上是关于c ++使基类在子类中使用覆盖的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift中使基类属性通用,以便可以与多种模型类型一起使用?

降低基类属性的可见性

基类指针和派生类指针

基类指针和派生类指针

如何生成扩展自定义记录类的 Doctrine 模型/类

人类VS机器:财富管理的下一个前沿