上一节中,函数重写遇上赋值兼容出现了问题:
34、35行调用的都是父类中的print函数。
35行我们给的实参是Child对象,期望调用子类中的print函数,但是运行结果并不是这样。
函数重写回顾:
子类中重定义父类中已有的函数,就是因为父类中的函数满足不了我们的需求。
我们期望的是只要是子类对象,调用的都是子类中的函数版本。
即使将子类对象赋值给父类指针或者引用,调用同名函数时我们也期望调用的是子类中的版本。
多态的概念和意义:
多态:
示例程序:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Parent 7 { 8 public: 9 virtual void print() 10 { 11 cout << "I'm Parent." << endl; 12 } 13 }; 14 15 class Child : public Parent 16 { 17 public: 18 void print() 19 { 20 cout << "I'm Child." << endl; 21 } 22 }; 23 24 void how_to_print(Parent* p) 25 { 26 p->print(); // 展现多态的行为 27 } 28 29 int main() 30 { 31 Parent p; 32 Child c; 33 34 how_to_print(&p); // Expected to print: I'm Parent. 35 how_to_print(&c); // Expected to print: I'm Child. 36 37 return 0; 38 }
第9行加上了virtual,这就是告诉编译器,这个函数在子类中有可能被重写。得考虑是不是要展现多态的行为。
编译器在遇到virtual就会做特殊的处理。
第18行的程序没有写virtual关键字,但是由于继承的关系,它就是virtual的,这里可写可不写。
运行结果如下:
多态的意义:
多态在编译时无法知道要调用哪一个函数,是在运行时决定的。
但凡发生函数重写,那么被重写的函数必然的是virtual的,因为我们需要多态,要不然我们也不会重写。
理论概念:
动态联编与静态联编:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Parent 7 { 8 public: 9 virtual void func() 10 { 11 cout << "void func()" << endl; 12 } 13 14 virtual void func(int i) 15 { 16 cout << "void func(int i) : " << i << endl; 17 } 18 19 virtual void func(int i, int j) 20 { 21 cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl; 22 } 23 }; 24 25 class Child : public Parent 26 { 27 public: 28 void func(int i, int j) 29 { 30 cout << "void func(int i, int j) : " << i + j << endl; 31 } 32 33 void func(int i, int j, int k) 34 { 35 cout << "void func(int i, int j, int k) : " << i + j + k << endl; 36 } 37 }; 38 39 void run(Parent* p) 40 { 41 p->func(1, 2); // 展现多态的特性 42 // 动态联编 43 } 44 45 46 int main() 47 { 48 Parent p; 49 50 p.func(); // 静态联编 51 p.func(1); // 静态联编 52 p.func(1, 2); // 静态联编 53 54 cout << endl; 55 56 Child c; 57 58 c.func(1, 2); // 静态联编 59 60 cout << endl; 61 62 run(&p); 63 run(&c); 64 65 return 0; 66 }
同名覆盖只能发生在父类和子类之间。
运行结果如下:
示例程序:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Boss 7 { 8 public: 9 int fight() 10 { 11 int ret = 10; 12 13 cout << "Boss::fight() : " << ret << endl; 14 15 return ret; 16 } 17 }; 18 19 class Master 20 { 21 public: 22 virtual int eightSwordKill() 23 { 24 int ret = 8; 25 26 cout << "Master::eightSwordKill() : " << ret << endl; 27 28 return ret; 29 } 30 }; 31 32 class NewMaster : public Master 33 { 34 public: 35 int eightSwordKill() 36 { 37 int ret = Master::eightSwordKill() * 2; 38 39 cout << "NewMaster::eightSwordKill() : " << ret << endl; 40 41 return ret; 42 } 43 }; 44 45 void field_pk(Master* master, Boss* boss) 46 { 47 int k = master->eightSwordKill(); 48 int b = boss->fight(); 49 50 if( k < b ) 51 { 52 cout << "Master is killed..." << endl; 53 } 54 else 55 { 56 cout << "Boss is killed..." << endl; 57 } 58 } 59 60 int main() 61 { 62 Master master; 63 Boss boss; 64 65 cout << "Master vs Boss" << endl; 66 67 field_pk(&master, &boss); 68 69 cout << "NewMaster vs Boss" << endl; 70 71 NewMaster newMaster; 72 73 field_pk(&newMaster, &boss); 74 75 return 0; 76 }
运行结果如下:
小结: