第48课 同名覆盖引发的问题
Posted wanmeishenghuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第48课 同名覆盖引发的问题相关的知识,希望对你有一定的参考价值。
父子间的赋值兼容:
子类对象兼容性实验:
第40行我们可以直接使用子类对象来初始化父类对象。这就是赋值兼容性。
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Parent 7 { 8 public: 9 int mi; 10 11 void add(int i) 12 { 13 mi += i; 14 } 15 16 void add(int a, int b) 17 { 18 mi += (a + b); 19 } 20 }; 21 22 class Child : public Parent 23 { 24 public: 25 int mv; 26 27 void add(int x, int y, int z) 28 { 29 mv += (x + y + z); 30 } 31 }; 32 33 int main() 34 { 35 Parent p; 36 Child c; 37 38 p = c; 39 40 Parent p1(c); 41 42 43 Parent& rp = c; 44 Parent* pp = &c; 45 46 rp.mi = 100; 47 rp.add(5); // 没有发生同名覆盖? 48 rp.add(10, 10); // 没有发生同名覆盖? 49 50 /* 为什么编译不过? */ 51 // pp->mv = 1000; 52 // pp->add(1, 10, 100); 53 54 return 0; 55 }
47、48不会发生同名覆盖,因为rp本身就是父类类型的引用,只不过引用的对象是子类对象。47、48行会直接去父类中找add函数,所以不会报错。
51、52行同时找不到mv和带三个参数的函数。这是因为pp是父类指针,它只会去父类中找对应的成员和函数。
使用父类指针或者引用绝对不能访问子类中的成员和函数。
特殊的同名函数:
在子类中重定义父类中已经存在的函数(名字和参数都一样),这叫函数重写,是特殊的同名覆盖。
函数重写是有必要的,因为对同一个函数,子类和父类可能表现出不同的动作。
思考:
当函数重写遇到赋值兼容会发生什么?
示例:
第47行的函数,如果子类中定义了print,如37行所示,则会打印39行的语句。将子类中的print函数注释掉,这时47行的函数调用的就是父类中的print,打印输出就如上图。
父类对象调用print就会打印父类中的print:
完善程序,添加全局打印函数:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Parent 7 { 8 public: 9 int mi; 10 11 void add(int i) 12 { 13 mi += i; 14 } 15 16 void add(int a, int b) 17 { 18 mi += (a + b); 19 } 20 21 void print() 22 { 23 cout << "I‘m Parent." << endl; 24 } 25 }; 26 27 class Child : public Parent 28 { 29 public: 30 int mv; 31 32 void add(int x, int y, int z) 33 { 34 mv += (x + y + z); 35 } 36 37 void print() 38 { 39 cout << "I‘m Child." << endl; 40 } 41 }; 42 43 void how_to_print(Parent* p) 44 { 45 p->print(); 46 } 47 48 int main() 49 { 50 Parent p; 51 Child c; 52 53 how_to_print(&p); // Expected to print: I‘m Parent. 54 how_to_print(&c); // Expected to print: I‘m Child. 55 56 return 0; 57 }
结果如下:
我们期望53、54行一个打印父类信息、一个打印子类信息,但是结果并不是这样,而是全部打印的是父类信息。
问题分析:
编译器的这种处理方法是合理的,但不是我们期望的,我们之所以在子类中重定义一个同名的函数版本,就是因为父类中的这个函数满足不了我们的需求。但是,运行发现,实际调用的还是父类中的版本。也就是当函数重写遇上赋值兼容就出现了问题。下一节我们探究解决方案。
小结:
以上是关于第48课 同名覆盖引发的问题的主要内容,如果未能解决你的问题,请参考以下文章