current position:Home>48 - Problems caused by overriding with the same name

48 - Problems caused by overriding with the same name

2022-11-24 22:40:30uwu16

---- 整理自狄泰软件唐佐林老师课程

1. 父子间的 赋值兼容

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

  • 子类对象可以 直接赋值 给父类对象
  • 子类对象可以 直接初始化 父类对象
  • 父类指针可以 直接指向子类对象
  • 父类引用可以 direct reference to subclass object

1.2 编程实验:子类对象的兼容性

#include <iostream>
#include <string>

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;
}

在这里插入图片描述

  • 当使用父类指针/When a reference points to a subclass object:
    • 子类对象 退化为父类对象
    • 只能访问父类中定义的成员(变量和函数)
    • 可以直接访问 子类覆盖的 同名成员

2. 特殊的同名函数

  • 子类中可以重定义父类中已经存在的成员函数
  • 这种重定义发生在继承中,叫做 函数重写
  • The function override is 同名覆盖 的一种特殊情况

在这里插入图片描述

2.1 思考

函数重写 遇上 赋值兼容 会发生什么?

2.2 编程实验:赋值兼容问题

#include <iostream>
#include <string>

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;
}

在这里插入图片描述
注解:当使用父类指针/When a reference points to a subclass object:子类对象退化为父类对象

2.3 问题分析

  • 编译期间,编译器只能根据指针的类型判断所指向的对象
  • 根据 赋值兼容,编译器认为父类指针指向的是父类对象
  • 因此,编译结果只可能是调用父类中定义的同名函数

在这里插入图片描述

  When compiling this function,It is impossible for the compiler to know about pointerspwhat does it point to.但是编译器没有理由报错.于是,编译器认为 The safest thing to do is to call the parent class'sprint函数,因为,Parent and child classes must have the sameprint函数.

2.4 问题

Is the compiler's approach reasonable??is it expected?

  • 是合理的,but not expected.

3. 小结

  • 子类对象可以当作父类对象使用(赋值兼容)
  • 父类指针可以正确的指向子类对象
  • 父类引用可以正确的代表子类对象
  • Member functions in the parent class can be overridden in the subclass

copyright notice
author[uwu16],Please bring the original link to reprint, thank you.
https://en.chowdera.com/2022/328/202211242224142114.html

Random recommended