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 }
虚继承是为了解决钻石继承的问题。