C++学习记录(七)多继承、菱形继承、类的转换、多态
这是第七天的学习。
1 #include <iostream>
2
3 using namespace std;
4 class Base
5 {
6 public:
7 int memb = 9;
8 public:
9 //Base() { cout << "Base" << endl; }
10 //Base(int init) {}
11 Base() = default;
12 ~Base() {cout << "~Base" << endl; }
13
14 virtual void showInfo() { cout << "Base memb is " << this->memb << endl; }
15 };
16
17 class Phone : virtual public Base
18 {
19 public:
20 int power;
21 public:
22 //Phone():Base::Base(1) { cout << "Phone" << endl; }
23 Phone() { cout << "Phone" << endl; }
24 ~Phone() { cout << "~Phone" << endl; }
25
26 virtual void show() { cout << "Show Phone" << endl; }
27 };
28 class Computer : virtual public Base
29 {
30 public:
31 // int power;
32 public:
33 //Computer():Base::Base(2) { cout << "Computer" << endl; }
34 Computer() { cout << "Computer" << endl; }
35 ~Computer() { cout << "~Computer" << endl; }
36
37 virtual void show() { cout << "Show Computer" <<endl; }
38 };
39
40 // 多继承
41 class Pad : public Phone, public Computer
42 {
43 public:
44 //Pad():Base::Base(3) { cout << "Pad" << endl; }
45 Pad() { cout << "Pad" << endl; }
46 ~Pad() { cout << "~Pad" << endl; }
47
48 int getPower() { return this->power; }
49 void show() override { cout << "Show Pad" << endl;};
50 };
51
52 class Keyboard : public Base
53 {
54 public:
55 int num = 96;
56 public:
57 Keyboard() { cout << "Keyboard" << endl; }
58 ~Keyboard() { cout << "~!Keyboard" << endl; }
59
60 void showInfo() override { cout << "Keyboard num is " << this->num << endl; }
61 };
62
63 class Mouse : public Base
64 {
65 public:
66 Mouse() { cout << "Mouse" << endl; }
67 ~Mouse() { cout << "~Mouse" << endl; }
68
69 void showInfo() override { cout << "Mouse info" << endl; }
70 };
71
72 int main()
73 {
74 // -1-多继承注意不要写同名的变量和函数,虚函数可以实现同名函数,
75 // 继承的类可以使用重载实现同名函数的定义
76 //Pad pad1;
77 //pad1.show();
78
79 // -2-菱形继承(1->2->4,1->3->4),会出现Base类的多次构造和析构
80 // 采用虚继承的方式可以解决这一个问题,代价是增加了内存。
81 // (ios->istream->iostream->fstream,ios->ostream->iostream->fstream)
82 //Pad pad2;
83 //cout << "Size of the class Pad is " << sizeof (pad2) << endl;
84
85 // -3-基类无默认空构造但含有参构造时,需子类初始化调用基类的有参构造
86 // 故写类时,最好写一个无参构造Base() = default
87 // Pad pad3;
88
89 // -4-类型的转换,四种转换方式
90 // 1.static_cast<type>(ref),可以从子类转父类
91 // int a = 65;
92 // cout << static_cast<char>(a) << endl; // 65,A
93 // 从父类先子类转型失败,但是不会报错
94 // Base b1;
95 // static_cast<Keyboard*>(&b1)->showInfo();
96
97 // 2.dynamic_cast<type>(ref),有继承关系的转换,父类中至少有一个虚函数
98 //Base* b2 = new Keyboard;
99 //dynamic_cast<Keyboard*>(b2)->showInfo();
100
101 // 3.const_cast<type>(ref),用转换const变量或引用
102 // 4.reinterpret_cast<type>(ref),强类型转换
103
104 // -5-多态,相同函数的多种实现形式:静态多态(函数重载),动态多态(虚函数)
105 // 父类的指针指向子类的对象时,调用的同名函数属于子类
106 // 编译器在编译虚函数时引入了一张虚函数表,并把虚表的首地址赋值给了虚指针
107 // 编译时生成虚表(保存虚函数的地址),构造对象时会把虚表地址赋值给子类继承的虚指针
108 Base* b3 = new Keyboard;
109 b3->showInfo();
110
111 cout << "Hello World!" << endl;
112 return 0;
113 }