![](/img/trans.png)
[英]c++ How do you call a template class function that is overloaded in the derived class, from the derived class?
[英]Call overloaded, derived function from C++ class on base object does not call the overloaded function
這是一個簡化的示例( 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)
或 sth。 類似於根據參數類型獲取“正確”值?
base->test(test)
base
是指向Base
的指針。 Base
有一個類方法叫做test()
。 這就是被調用的類方法。 由於該類方法的參數是Base *
,因此test
被轉換為。 這就是 C++ 中類型轉換的工作原理。
base
指向派生對象的基類,它覆蓋了該虛擬方法。 派生類中采用Base *
的被覆蓋方法被調用,因為這是被覆蓋的方法。
指針在轉換之前指向Test *
的事實並不重要。 Base
中沒有將Test *
作為參數的函數,唯一一個將Base *
作為參數的函數,所以這就是被調用的函數。
當您轉換一個類時,最具體的信息與您將其轉換到的層次結構中的類型相關。
Base
vtable沒有該重載,因此編譯器無法在編譯時知道另一個重載存在。
如果您考慮如何實現動態調度,那么為什么您的代碼無法正常工作是微不足道的,我不明白它是如何實現的。
您應該提供您正在嘗試解決的確切問題,因為您嘗試做的事情可能有不同的解決方案,因為它看起來像一個 XY 問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.