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()就不行。