第54课 被遗弃的多重继承(下)

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第54课 被遗弃的多重继承(下)相关的知识,希望对你有一定的参考价值。

多重继承问题3:

技术分享图片

 

示例:

技术分享图片

用pbb指针去掉用funcB函数,结果打印的是funcA。这是不期望的。

问题分析:

这是由于第34行的强制类型转换造成的。

技术分享图片

 

 程序改进:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class BaseA
 7 {
 8 public:
 9     virtual void funcA()
10     {
11         cout << "BaseA::funcA()" << endl;
12     }
13 };
14 
15 class BaseB
16 {
17 public:
18     virtual void funcB()
19     {
20         cout << "BaseB::funcB()" << endl;
21     }
22 };
23 
24 class Derived : public BaseA, public BaseB
25 {
26 
27 };
28 
29 int main()
30 {
31     Derived d;
32     BaseA* pa = &d;
33     BaseB* pb = &d;
34     BaseB* pbe = (BaseB*)pa;    // oops!!
35     BaseB* pbc = dynamic_cast<BaseB*>(pa);
36     
37     cout << "sizeof(d) = " << sizeof(d) << endl;
38     
39     cout << "Using pa to call funcA()..." << endl;
40     
41     pa->funcA();
42     
43     cout << "Using pb to call funcB()..." << endl;
44     
45     pb->funcB();
46     
47     cout << "Using pbc to call funcB()..." << endl;
48     
49     pbc->funcB();
50     
51     cout << endl;
52     
53     cout << "pa = " << pa << endl;
54     cout << "pb = " << pb << endl;
55     cout << "pbe = " << pbe << endl;
56     cout << "pbc = " << pbc << endl;
57     
58     return 0;
59 }

使用dynamic_cast做类型转换时,会有一个对指针修正的过程。暴力的强制类型转换没有指针修正过程。

结果如下:

技术分享图片

 

工程中正确的使用多重继承:

技术分享图片

 

示例程序:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Base
 7 {
 8 protected:
 9     int mi;
10 public:
11     Base(int i)
12     {
13         mi = i;
14     }
15     int getI()
16     {
17         return mi;
18     }
19     bool equal(Base* obj)
20     {
21         return (this == obj);
22     }
23 };
24 
25 class Interface1
26 {
27 public:
28     virtual void add(int i) = 0;
29     virtual void minus(int i) = 0;
30 };
31 
32 class Interface2
33 {
34 public:
35     virtual void multiply(int i) = 0;
36     virtual void divide(int i) = 0;
37 };
38 
39 class Derived : public Base, public Interface1, public Interface2
40 {
41 public:
42     Derived(int i) : Base(i)
43     {
44     }
45     void add(int i)
46     {
47         mi += i;
48     }
49     void minus(int i)
50     {
51         mi -= i;
52     }
53     void multiply(int i)
54     {
55         mi *= i;
56     }
57     void divide(int i)
58     {
59         if( i != 0 )
60         {
61             mi /= i;
62         }
63     }
64 };
65 
66 int main()
67 {
68     Derived d(100);
69     Derived* p = &d;
70     Interface1* pInt1 = &d;
71     Interface2* pInt2 = &d;
72     
73     cout << "p->getI() = " << p->getI() << endl;    // 100
74     
75     pInt1->add(10);
76     pInt2->divide(11);
77     pInt1->minus(5);
78     pInt2->multiply(8);
79     
80     cout << "p->getI() = " << p->getI() << endl;    // 40
81     
82     cout << endl;
83     
84     cout << "pInt1 == p : " << p->equal(dynamic_cast<Base*>(pInt1)) << endl;
85     cout << "pInt2 == p : " << p->equal(dynamic_cast<Base*>(pInt2)) << endl;
86     
87     return 0;
88 }

接口是由纯虚函数构成的抽象类。

基类是Base。

第39行在语法上是多继承,但是概念上是单继承并实现多个接口。

equal函数判断参数指针是否指向当前对象。

运行结果:

技术分享图片

 

 建议:

技术分享图片

 

小结:

技术分享图片

 

以上是关于第54课 被遗弃的多重继承(下)的主要内容,如果未能解决你的问题,请参考以下文章

第53课 被遗弃的多重继承 (下)——正确的使用多重继承

第53课 被遗弃的多重继承

第53课 被遗弃的多重继承(上)

第53课 被遗弃的多重继承 (中)

第53课 被遗弃的多重继承(上)

C++--被遗弃的多重继承经典问题