C++虛函數和函數指針一起使用,寫起來有點麻煩。
下面貼出一份示例代碼,可作參考。(需要支持C++11編譯)
1 #include <stdio.h> 2 #include <list> 3 using namespace std; 4 5 class VirtualWithCallBack { 6 public: 7 using CallBack = void(VirtualWithCallBack::*)(int); 8 9 public: 10 virtual void testCallBack(int arg) = 0; 11 12 virtual CallBack getCallBack() const = 0; 13 }; 14 15 class VirtualWithCallBackSample1 : public VirtualWithCallBack { 16 public: 17 VirtualWithCallBackSample1() { 18 callBack = &VirtualWithCallBack::testCallBack; 19 } 20 21 public: 22 void testCallBack(int arg) override { 23 printf("This is virtual call 1 : arg = %d\n", arg); 24 } 25 26 CallBack getCallBack() const override { 27 return callBack; 28 } 29 30 private: 31 CallBack callBack = nullptr; 32 }; 33 34 class VirtualWithCallBackSample2 : public VirtualWithCallBack { 35 public: 36 VirtualWithCallBackSample2() { 37 callBack = &VirtualWithCallBack::testCallBack; 38 } 39 40 public: 41 void testCallBack(int arg) override { 42 printf("This is virtual call 2 : arg = %d\n", arg); 43 } 44 45 CallBack getCallBack() const override { 46 return callBack; 47 } 48 49 private: 50 CallBack callBack = nullptr; 51 }; 52 53 class VirtualCaller { 54 public: 55 void push(VirtualWithCallBack* callBack) { 56 callBackList.push_back(callBack); 57 } 58 59 void run() { 60 for (auto r : callBackList) { 61 (r->*(r->getCallBack()))(99); 62 } 63 } 64 65 private: 66 list<VirtualWithCallBack*> callBackList; 67 }; 68 69 int main() { 70 VirtualCaller caller; 71 caller.push(new VirtualWithCallBackSample1()); 72 caller.push(new VirtualWithCallBackSample2()); 73 caller.run(); 74 return 0; 75 }
運行結果
本文由 哈薩雅琪 原創,轉載請注明出處。
你這個是已經是子類轉換成父類對象了,本質就是一個父類了。而且是個值傳遞,只是用值來構造一個父類,與虛函數沒關系的。你如果弄成引用應該就可以了,改成如下,只是改動class c
class C
{
public:
void print(A &a) //引用,並不是值傳遞
{
a.print();
}
};
((CO*)(C1*)&obj)->print();和obj.print()是一樣的。
前面那個就是強制類型轉換。
由於是子類往父類轉,所以不需要額外的實現,自動就完成了。
這只是編譯器的花招。
寫((C0*)&obj)->print();之所以不行,是因為有歧義。你不知道是C2的C0還是C1的C0,不要忘了,你前面是多繼承,也就是說,有兩個C0。所以,要寫((CO*)(C1*)&obj)->print();因為在C0的聲明中print是公共的,所以可以調用。obj.print()就不行。