c++ - 在基对象上调用来自 C++ 类的重载、派生函数不会调用重载函数

标签 c++ c++17 overloading

这是一个简化的示例 ( OnlineGDB ):

#include <iostream>

using namespace std;

class Base {
public:
    virtual ~Base() {}
    virtual int test(Base* parent) = 0;
};

class Test : public Base {
public:
    ~Test() {}
    int test(Base* parent) { return 10; }
    int test(Test* parent) { return 20; }
};

int main(int argc, char* argv[]) {
    Test* test = new Test();
    Base* base = test;

    cout << test->test(test) << endl; // prints 20
    cout << base->test(test) << endl; // prints 10
    
    return 0;
}

我希望这两个调用都会返回 20 ,因为参数的类型为 Test ,但第二次调用返回 10 .

我知道我可以dynamic_cast<Test*>(base)->test(test)它再次起作用,但实际上我有更多源自 Base 的类。我当然可以做某事。像这样:

auto test1 = dynamic_cast<Test*>(base);
if (test1) {
    test1->test(test);
}

auto test2 = dynamic_cast<Test2*>(base);
if (test2) {
    test2->test(test);
}

...

但是对于任何源自 Base 的新类这需要进行调整,并且代码中有多个部分必须执行此操作。

有什么办法可以让我保留base->test(test)或某事。类似于根据参数类型获取“正确”值?

最佳答案

base->test(test) 

base 是指向Base 的指针。 Base 只有一个名为 test() 的类方法。这就是被调用的类方法。由于该类方法的参数是 Base *,因此 test 会转换为该参数。这就是 C++ 中类型转换的工作原理。

base 指向派生对象的基类,该基类重写该虚拟方法。派生类中采用 Base * 的重写方法将被调用,因为这是重写的方法。

在转换之前,指针指向 Test * 的事实并不重要。 Base 中没有任何函数将 Test * 作为参数,唯一一个将 Base * 作为参数,所以这就是一个被调用的。

关于c++ - 在基对象上调用来自 C++ 类的重载、派生函数不会调用重载函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73093575/

相关文章:

interface - F# 和接口(interface)实现的成员

尝试重载运算符和使用类模板时出现 C++ 错误

c++ - 一个函数可以返回一个指向它自己类型的指针吗?

关于模板等价/重新定义的 C++ 规则?

c++ - 如何将 boost::string_view 转换为 std::string_view?

types - 比较不同类型的值

c++ - 在模板化函数不明确的情况下表达偏好

c++ - 声明指向 *this* 对象的指针的优点或原因是什么?

c# - 如何创建包含 const 内容的 C# 列表?

c++ - Windows Messaging - 获取非客户区设备上下文的各种方法