具有相同名称但参数和返回类型不同的虚拟函数[重复]

Posted

技术标签:

【中文标题】具有相同名称但参数和返回类型不同的虚拟函数[重复]【英文标题】:Virtual functions with same name but different arguments and return types [duplicate] 【发布时间】:2019-06-09 11:39:33 【问题描述】:

我在一次采访中被问到这个问题。我的答案是(3 和 3.6)(错误)。 请解释我的理解是错误的

我的想法是指针bd会指向派生类vtable的_vptr。

Derived 类的 Vtable 将包含 2 个函数

double func(double) // ----->points to Derived::func()
int func(int)       // ----->points to Base::func()

因此,

bd->func(2)   // will call Base::func() i.e int func(int)
bd->func(2.3) // will call Derived::func() i.e double func(double)

请解释我的理解是错误的。 另外,解释Base::func() 不是virtual 的情况。 在那种情况下,就不会有vtable了吧?如何解决函数调用?

#include <iostream>    
using namespace std;

class Base

private:
    /* data */
public:
    Base(/* args */);
    ~Base();

    //int func(int i)     getting same answer regardless of virtual
    virtual int func(int i)
    
        cout << "Base func()" << endl;
        return i+1;
    
;

class Derived : public Base

public:
    Derived(/* args */);
    ~Derived();

    double func(double d)
    
        cout << "Derived func()" << endl;
        return d+1.3;
    
;

int main() 
    Base* bd = new Derived();
    cout << bd->func(2) << endl;
    cout << bd->func(2.3) << endl;
    return 0;

预期输出:

Base func()
3
Derived func()
3.6

Actual output:
Base func()
3
Base func()
3

【问题讨论】:

【参考方案1】:

Base 中没有使用double 的函数。你所拥有的只是一个指向Base 的指针。所以 2.3 被截断为int2 并调用Base::func(int i)

Derived::func(double d) 在这段代码中根本不起作用。

funcBase 中是virtual 并不重要,因为Derived 中的func 不是override 它(签名不匹配)。将 override 关键字添加到 Base::func 将立即将其作为编译器错误清除。

【讨论】:

bdvptr 不是指向派生类虚拟表吗?如果是,则应在bd-&gt;func(2.3) 上调用Derived::func() @mohit bd 的静态类型是Base*,所以最初你会点击Base::func。该函数是virtual,因此如果类中有dynamic 类型(Derived)匹配的覆盖函数,它将被调用。但是没有这样的功能,因为Derived::func 实际上并不是override Base::func。所以Base::func 被调用了。 在编译时,bd 指向 Base。所以 2.3 在编译时被转换为整数 2 并解析为Base::func()。因此,在运行时,程序将搜索int func(int) 的覆盖版本(因为它在编译时已经将bd-&gt;func(2.3) 视为int func(int) 类型),它不会在派生类中找到。这种理解正确吗? 没有。这不是它的工作原理。我不知道如何解释得比我已经做过的更好。也许其他人可以。 好的。没问题。感谢所有帮助

以上是关于具有相同名称但参数和返回类型不同的虚拟函数[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C#中具有相同名称和签名但返回类型不同的方法

C#中具有相同名称和签名但返回类型不同的方法

C ++如何从具有不同返回类型的接口多重继承?

方法的重载

函数的简单介绍

请简述重载和重写的区别