C++_day8_ 多重继承、钻石继承和虚继承

1.继承的复习

1.1 类型转换

编译器认为访问范围缩小是安全的。

1.2 子类的构造与析构

子类中对基类构造函数初始化只能写在初始化表里,不能写在函数体中。

阻断继承。

1.3 子类的拷贝构造与拷贝赋值

 

2. 多重继承、钻石继承和虚继承

  • 多重继承

  一个类可以同时从多个基类继承实现代码。

  

  

  示例代码:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Phone{
 6 public:
 7     Phone(string const& no):m_no(no){
 8         cout << "Phone构造" << this << endl;
 9     }
10     ~Phone(void)
11     {
12         cout << "Phone析构" << this << endl;
13     }
14     void call (string const& no)
15     {
16         cout << m_no << "呼叫" << no << endl;
17     }
18 private:
19     string m_no;
20 };
21 
22 class Player{
23 public:
24     Player(string const& media):m_media(media)
25     {
26         cout << "Player构造" << this << endl;
27     }
28     ~Player(void)
29     {
30         cout << "Player析构" << this << endl;
31     }
32     void play(string const& clip)
33     {
34         cout << m_media << "播放" << clip << endl;
35     }
36 private:
37     string m_media;
38 };
39 
40 class Computer{
41 public:
42     Computer(string const& os):m_os(os)
43     {
44         cout << "Computer构造" << this << endl;
45     }
46     ~Computer(void)
47     {
48         cout << "Computer析构" << this << endl;
49     }
50     void run(string const& app)
51     {
52         cout << "" << m_os << "上运行" << app << endl;
53     }
54 private:
55     string m_os;
56 };
57 
58 class SmartPhone:public Phone, public Player, public Computer{
59 public:
60     SmartPhone (string const& no, string const& media, string const& os):Phone(no), Player(media), Computer(os){}
61 private:
62 };
63 
64 int main(void)
65 {
66     SmartPhone sp("17816120319", "MP3/MP4/3GP", "Andriod");
67     sp.call("17095400176");
68     sp.play("我还年轻");
69     sp.run("JBG大战Victor Wang");
70     Phone* pPhone = &sp;    //访问范围缩小,不会报错
71     cout << "&sp = " << &sp << endl;
72     cout << "pPhone = " << pPhone << endl;
73     Player* pPlayer = &sp;
74     cout << "pPlayer = " << pPlayer << endl;
75     Computer* pComputer = &sp;
76     cout << "pComputer = " << pComputer << endl;
77     /*
78     SmartPhone* pSmart = static_cast<SmartPhone*> (pComputer);
79     cout << "pSmart = " << pSmart << endl;
80     */
81     
82     /*
83     SmartPhone* pSmart = (SmartPhone*) pComputer;
84     cout << "pSmart = " << pSmart << endl;
85     */
86     
87     SmartPhone* pSmart = reinterpret_cast <SmartPhone*> (pComputer);
88     cout << "pSmart = " << pSmart << endl;
89     
90     return 0;
91 }

   

  名字冲突问题:

  1.

1 class C: public A, public B{
2 public:
3     using A::foo;
4     using B::foo;
5     
6 };

  2.

1 /*
2     c.A::foo();
3     c.B::foo(100);
4     */

  3.

 1 class C: public A, public B{
 2 public:
 3 /*
 4     using A::foo;
 5     using B::foo;
 6     */
 7     void foo(int f, int x)
 8     {
 9         if(f == 1)
10             A::foo();
11         else if(f == 2)
12             B::foo(x);
13     }
14 };

 

  • 钻石继承

     一个子类继承自多个基类,而这些基类有源自共同的祖先,这样的继承结构成为钻石继承(菱形继承)。

  

  

  

 

  • 虚继承

  

  示例代码:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class A{
 6 public:
 7     A(int data):m_data(data)
 8     {
 9         cout << "A构造" << this << endl;
10     }
11 protected:
12     int m_data;
13 };
14 
15 class B: virtual public A {
16 public:
17     B(int data): A(data)
18     {
19         cout << "B构造" << this << endl;
20     }
21     void set(int data)
22     {
23         cout << "B:" << &m_data << endl;
24         m_data = data;
25     }
26 };
27 
28 class C: virtual public A {
29 public:
30     C(int data): A(data)
31     {
32         cout << "C构造" << this << endl;
33     }
34     int get (void) const
35     {
36         cout << "C:" << &m_data << endl;
37         return m_data;
38     }
39 };
40 
41 class D: public B, public C{
42 public:
43     D(int data):B(data), C(data), A(data) {}
44 };
45 
46 int main(void)
47 {
48     D d(100);
49     d.set(200);
50     cout << d.get() << endl;
51     cout << sizeof(d) << endl;
52     
53     return 0;
54 }

 虚继承是为了解决钻石继承的问题。

posted @ 2019-04-20 14:30  鸿蒙过客  阅读(295)  评论(0编辑  收藏  举报