48-同名覆盖引发的问题

父子间的赋值兼容

子类对象可以当作父类对象使用(兼容性):

1、子类对象可以直接赋值给父类对象

2、子类对象可以直接初始化父类对象

3、父类指针可以直接指向子类对象

4、父类引用可以直接引用子类对象

【范例代码】子类对象的兼容性

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Parent {
 7 public:
 8     int mi;
 9 
10     void add(int i) {
11         mi += i;
12     }
13 
14     void add(int a, int b) {
15         mi += (a + b);
16     }
17 };
18 
19 class Child : public Parent {
20 public:
21     int mv;
22 
23     void add(int x, int y, int z) {
24         mv += (x + y + z);
25     }
26 };
27 
28 int main(int argc, const char* argv[]) {
29     Parent p;
30     Child c;
31 
32     p = c;
33 
34     Parent p1(c);
35 
36     Parent& rp = c;
37     Parent* pp = &c;
38 
39     rp.mi = 100;
40     rp.add(5);             // 没有发生同名覆盖?
41     rp.add(10, 10);        // 没有发生同名覆盖?
42 
43     /* 为什么编译不过? */
44     // pp->mv = 1000;
45     // pp->add(1, 10, 100);
46 
47     return 0;
48 }

当使用父类指针(引用)指向子类对象时:

1、子类对象退化父类对象

2、只能访问父类中定义的成员

3、可以直接访问被子类覆盖的同名成员

特殊的同名函数

1、子类中可以重定义父类中已经存在的成员函数

2、这种重定义发生在继承中,叫做函数重写

3、函数重写是同名覆盖的一种特殊情况

【思考】当函数重写遇上赋值兼容会发生什么?

【范例代码】赋值兼容的问题

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Parent {
 7 public:
 8     int mi;
 9 
10     void add(int i) {
11         mi += i;
12     }
13 
14     void add(int a, int b) {
15         mi += (a + b);
16     }
17 
18     void print() {
19         cout << "I'm Parent." << endl;
20     }
21 };
22 
23 class Child : public Parent {
24 public:
25     int mv;
26 
27     void add(int x, int y, int z) {
28         mv += (x + y + z);
29     }
30 
31     void print() {
32         cout << "I'm Child." << endl;
33     }
34 };
35 
36 void how_to_print(Parent* p) {
37     p->print();
38 }
39 
40 int main(int argc, const char* argv[]) {
41     Parent p;
42     Child c;
43 
44     how_to_print(&p);    // Expected to print: I'm Parent.
45     how_to_print(&c);    // Expected to print: I'm Child.
46 
47     return 0;
48 }

问题分析:

1、编译期间,编译器只能根据指针的类型判断所指向的对象

2、根据赋值兼容,编译器认为父类指针指向的是父类对象

3、因此,编译结果只可能是调用父类中定义的同名函数

【问题】编译器的处理方法是合理的吗?是期望的吗?

猜你喜欢

转载自www.cnblogs.com/laoyaodada/p/9168075.html