从超类的指针调用时,基类函数不会覆盖超类函数

Posted

技术标签:

【中文标题】从超类的指针调用时,基类函数不会覆盖超类函数【英文标题】:Base class function not overriding superclass function when called from a pointer of the superclass 【发布时间】:2013-03-10 05:10:00 【问题描述】:

我有一个类sub,它继承自一个类super。它们都定义了一个函数void function()(所以sub 中的函数会覆盖super 中的函数)。我创建了一个super 指针并为其分配了一个sub 的新实例。然后我通过super 指针在sub 的实例上调用function()。但是,调用的是super 中的函数,而不是sub 中的函数。我希望它调用sub 中的函数,而不是super 中的函数。我该怎么做?

#include <cstdio>  

class super   
    public:
    void function()   
        printf("Super\n");  
      
;  

class sub: public super   
    public:  
    void function()   
        printf("Sub\n");  
      
;  

int main()   
    super *p;  
    p = new sub;  
    p->function();  
    return 0;  

【问题讨论】:

函数默认不是虚拟的。 C++ Inheritance, calling a derived function from the base class的可能重复 您可以在调用函数之前将指针转换为您的子类。 ((sub *)p)-&gt;function(); 【参考方案1】:

声明应该是:

virtual void function()

我对 C++ 生疏了,但基本上如果函数不是虚拟的,编译器会告诉你,如果指针指向一个 super,function() 调用将转到 super::function() . Virtual 告诉它你希望它找出正确的。实际上,这意味着它将创建一个 vtable,并进行间接查找。那么无论是 super* 还是 sub* 都没有关系,因为它们都会有一个 vtable,并且 vtable 会针对对象的实际类型指向正确的 function() 版本。

【讨论】:

【参考方案2】:
class super   
    public:
    virtual void function()   
        printf("Super\n");  
      
;

【讨论】:

【参考方案3】: 要使用基类指针调用派生类函数,您需要实现称为函数覆盖的概念。 但在您的情况下,您实现了函数隐藏,而不是函数覆盖。 要重写函数,派生类和基类都应该具有相同的函数签名,并且必须使用 virtual 关键字声明基类函数声明。 如果您在基类声明中使用 virtual 关键字,则内存中的虚拟表将负责调用类链的大多数派生函数。

如需更多了解,请阅读以下内容:

Function Hiding Function Overriding Virtual Table

【讨论】:

以上是关于从超类的指针调用时,基类函数不会覆盖超类函数的主要内容,如果未能解决你的问题,请参考以下文章

从超类调用子类的方法

如何键入提示 Python 函数返回从超类派生的任何类的实例?

Python子类方法从超类方法继承装饰器

父类中的方法被覆盖以及子类调用父类覆盖的方法

Swift - 在超类的覆盖函数中返回子类类型

从超类调用子类方法