我有基类和虚方法fun
。我需要重新定义派生类中的所有fun
方法。我知道SO: C++ virtual override functions with same name,但它对我不起作用。
功能processDerived
接受v1::Derived *
。如果我通过v2::Derived *
,它就无法正常工作。
class Base1 {
public:
virtual ~Base1() {}
virtual void funB1_1() {}
virtual void funB1_2() {}
virtual void fun() { std::cout << "Base1::fun()" << std::endl; }
};
class Base2 {
public:
virtual ~Base2() {}
virtual void fun() { std::cout << "Base2::fun()" << std::endl; }
virtual void funB2() {}
};
namespace v1 {
class Derived : public Base1, public Base2 {
int x_;
public:
Derived() : x_(10) {}
virtual ~Derived() {}
virtual void funD1(int i) { std::cout << "Derived::funD1(" << i << ")" << std::endl; }
};
}
namespace v2 {
class Base1Proxy : public Base1 {
public:
virtual ~Base1Proxy() {}
virtual void fun() override { fun_Base1(); }
protected:
virtual void fun_Base1() = 0;
};
class Base2Proxy : public Base2 {
public:
virtual ~Base2Proxy() {}
virtual void fun() override { fun_Base2(); }
protected:
virtual void fun_Base2() = 0;
};
class Derived : public Base1Proxy, public Base2Proxy {
int x_;
public:
Derived() : x_(10) {}
virtual ~Derived() {}
virtual void funD1(int i) { std::cout << "Derived::funD1(" << i << ")" << std::endl; }
protected:
virtual void fun_Base1() override { std::cout << "Derived::Base1::fun(), x = " << x_ << std::endl; }
virtual void fun_Base2() override { std::cout << "Derived::Base2::fun(), x = " << x_ << std::endl; }
};
}
void processDerived(v1::Derived * d, int i) {
d->funD1(i);
}
int main() {
v1::Derived d;
Base1 * b1 = &d;
Base2 * b2 = &d;
b1->fun();
b2->fun();
processDerived(&d, 100);
v2::Derived d2;
b1 = &d2;
b2 = &d2;
b1->fun();
b2->fun();
processDerived(reinterpret_cast<v1::Derived *>(&d2), 200);
}
输出:
Base1::fun()
Base2::fun()
Derived::funD1(100)
Derived::Base1::fun(), x = 10
Derived::Base2::fun(), x = 10
Derived::Base1::fun(), x = 10 // expected Derived::funD1(200)
VTABLES(由MSVC生成):
; COMDAT ??_7Derived@v2@@6BBase2Proxy@1@@
CONST SEGMENT
??_7Derived@v2@@6BBase2Proxy@1@@ DQ FLAT:??_R4Derived@v2@@6BBase2Proxy@1@@ ; v2::Derived::`vftable'
DQ FLAT:??_EDerived@v2@@W7EAAPEAXI@Z
DQ FLAT:?fun@Base2Proxy@v2@@UEAAXXZ
DQ FLAT:?funB2@Base2@@UEAAXXZ
DQ FLAT:?fun_Base2@Derived@v2@@MEAAXXZ
CONST ENDS
; COMDAT ??_7Derived@v2@@6BBase1Proxy@1@@
CONST SEGMENT
??_7Derived@v2@@6BBase1Proxy@1@@ DQ FLAT:??_R4Derived@v2@@6BBase1Proxy@1@@ ; v2::Derived::`vftable'
DQ FLAT:??_EDerived@v2@@UEAAPEAXI@Z
DQ FLAT:?funB1_1@Base1@@UEAAXXZ
DQ FLAT:?funB1_2@Base1@@UEAAXXZ
DQ FLAT:?fun@Base1Proxy@v2@@UEAAXXZ
DQ FLAT:?fun_Base1@Derived@v2@@MEAAXXZ
DQ FLAT:?funD1@Derived@v2@@UEAAXH@Z
CONST ENDS
; COMDAT ??_7Base2Proxy@v2@@6B@
CONST SEGMENT
??_7Base2Proxy@v2@@6B@ DQ FLAT:??_R4Base2Proxy@v2@@6B@ ; v2::Base2Proxy::`vftable'
DQ FLAT:??_EBase2Proxy@v2@@UEAAPEAXI@Z
DQ FLAT:?fun@Base2Proxy@v2@@UEAAXXZ
DQ FLAT:?funB2@Base2@@UEAAXXZ
DQ FLAT:_purecall
CONST ENDS
; COMDAT ??_7Base1Proxy@v2@@6B@
CONST SEGMENT
??_7Base1Proxy@v2@@6B@ DQ FLAT:??_R4Base1Proxy@v2@@6B@ ; v2::Base1Proxy::`vftable'
DQ FLAT:??_EBase1Proxy@v2@@UEAAPEAXI@Z
DQ FLAT:?funB1_1@Base1@@UEAAXXZ
DQ FLAT:?funB1_2@Base1@@UEAAXXZ
DQ FLAT:?fun@Base1Proxy@v2@@UEAAXXZ
DQ FLAT:_purecall
CONST ENDS
; COMDAT ??_7Derived@v1@@6BBase2@@@
CONST SEGMENT
??_7Derived@v1@@6BBase2@@@ DQ FLAT:??_R4Derived@v1@@6BBase2@@@ ; v1::Derived::`vftable'
DQ FLAT:??_EDerived@v1@@W7EAAPEAXI@Z
DQ FLAT:?fun@Base2@@UEAAXXZ
DQ FLAT:?funB2@Base2@@UEAAXXZ
CONST ENDS
; COMDAT ??_7Derived@v1@@6BBase1@@@
CONST SEGMENT
??_7Derived@v1@@6BBase1@@@ DQ FLAT:??_R4Derived@v1@@6BBase1@@@ ; v1::Derived::`vftable'
DQ FLAT:??_EDerived@v1@@UEAAPEAXI@Z
DQ FLAT:?funB1_1@Base1@@UEAAXXZ
DQ FLAT:?funB1_2@Base1@@UEAAXXZ
DQ FLAT:?fun@Base1@@UEAAXXZ
DQ FLAT:?funD1@Derived@v1@@UEAAXH@Z
CONST ENDS
; COMDAT ??_7Base2@@6B@
CONST SEGMENT
??_7Base2@@6B@ DQ FLAT:??_R4Base2@@6B@ ; Base2::`vftable'
DQ FLAT:??_EBase2@@UEAAPEAXI@Z
DQ FLAT:?fun@Base2@@UEAAXXZ
DQ FLAT:?funB2@Base2@@UEAAXXZ
CONST ENDS
; COMDAT ??_7Base1@@6B@
CONST SEGMENT
??_7Base1@@6B@ DQ FLAT:??_R4Base1@@6B@ ; Base1::`vftable'
DQ FLAT:??_EBase1@@UEAAPEAXI@Z
DQ FLAT:?funB1_1@Base1@@UEAAXXZ
DQ FLAT:?funB1_2@Base1@@UEAAXXZ
DQ FLAT:?fun@Base1@@UEAAXXZ
CONST ENDS
如您所见,方法(1)被调用而不是(2)
; old Derived::`vftable'
DQ FLAT:??_EDerived@v1@@UEAAPEAXI@Z
DQ FLAT:?funB1_1@Base1@@UEAAXXZ
DQ FLAT:?funB1_2@Base1@@UEAAXXZ
DQ FLAT:?fun@Base1@@UEAAXXZ
DQ FLAT:?funD1@Derived@v1@@UEAAXH@Z
; new Derived::`vftable'
DQ FLAT:??_EDerived@v2@@UEAAPEAXI@Z
DQ FLAT:?funB1_1@Base1@@UEAAXXZ
DQ FLAT:?funB1_2@Base1@@UEAAXXZ
DQ FLAT:?fun@Base1Proxy@v2@@UEAAXXZ
DQ FLAT:?fun_Base1@Derived@v2@@MEAAXXZ ; <== (1)
DQ FLAT:?funD1@Derived@v2@@UEAAXH@Z ; <== (2)
我的案子有解决方案吗?
P.S。 我知道MSVC特定的解决方案,但我需要它为GCC,Clang,Apple-Clang工作。