下面看一个子类对象兼容性的代码:
- #include
- #include
-
- using namespace std;
-
- class Parent
- {
- public:
- int mi;
-
- void add(int i)
- {
- mi += i;
- }
-
- void add(int a, int b)
- {
- mi += (a + b);
- }
- };
-
- class Child : public Parent
- {
- public:
- int mv;
-
- void add(int x, int y, int z)
- {
- mv += (x + y + z);
- }
- };
-
- int main()
- {
- Parent p;
- Child c;
-
- p = c;
-
- Parent p1(c);
-
-
- Parent& rp = c;
- Parent* pp = &c;
-
- rp.mi = 100;
- rp.add(5); // 没有发生同名覆盖?
- rp.add(10, 10); // 没有发生同名覆盖?
-
- /* 为什么编译不过? */
- // pp->mv = 1000;
- // pp->add(1, 10, 100);
-
- return 0;
- }
其中下面的代码可以正常编译,没有发生同名覆盖
- rp.mi = 100;
- rp.add(5); // 没有发生同名覆盖?
- rp.add(10, 10); // 没有发生同名覆盖?
而下面的代码编译不过
- // pp->mv = 1000;
- // pp->add(1, 10, 100);

下面揭晓答案:

思考:当函数重写遇上赋值兼容会怎么样?
下面看一个赋值兼容的代码:
- #include
- #include
-
- using namespace std;
-
- class Parent
- {
- public:
- int mi;
-
- void add(int i)
- {
- mi += i;
- }
-
- void add(int a, int b)
- {
- mi += (a + b);
- }
-
- void print()
- {
- cout << "I'm Parent." << endl;
- }
- };
-
- class Child : public Parent
- {
- public:
- int mv;
-
- void add(int x, int y, int z)
- {
- mv += (x + y + z);
- }
-
- void print()
- {
- cout << "I'm Child." << endl;
- }
- };
-
- void how_to_print(Parent* p)
- {
- p->print();
- }
-
- int main()
- {
- Parent p;
- Child c;
-
- how_to_print(&p); // Expected to print: I'm Parent.
- how_to_print(&c); // Expected to print: I'm Child.
-
- return 0;
- }
输出结果如下:


在编译这个函数的时候,编译器不可能知道指针 p 究竟指向了什么。但是编译器没有理由报错。于是,编译器认为最安全的做法是调用父类的 print 函数,因为父类和子类肯定都有相同的 print 函数。
问题:编译器的处理方法是合理的吗?是期望的吗?
编译器的处理方法是合理的,但不是我们期望的,我们期望的是子类对象调用子类的 printf 函数,父类对象调用父类的 printf 函数