C++ 多态问题引入:子类和父类同名函数使用virtual实现多态

#include 
using namespace std;

// 定义一个子类和一个父类
class Parent {
public:
    Parent(int a = 0) {
        this->a = a;
    }
    void print() {
        cout << "父类 a: " << a << endl;
    }
protected:
private:
    int a;
};

class Child : public Parent {
public:
    Child(int b = 0) {
        this->b = b;
    }
    void print() {
        cout << "子类 b: " << b << endl;
    }
protected:
private:
    int b;
};

// 现象产生的原因
// 赋值兼容性原则遇上函数重写
// 对被调用函数来讲,在编译器编译期间,就确定了参数p,是Parent类型的
// 是静态链接编译,所以始终执行父类的print()函数
void toPrint1(Parent* p) {
    p->print();
}

void toPrint2(Parent& p) {
    p.print();
}

// 面向对象新需求:
// 如果传入父类对象,执行父类的print函数
// 如果传入子类对象,执行子类的print函数
// 这个功能的需求就是多态
// 需要在父类的print()函数前,添加virtual

void main01() {
    Parent p1;
    Child c1;
    /*
    //p1.print();
    //c1.print();

    //赋值兼容性原则
    Parent* p = NULL;
    p = &p1;
    p->print(); // 调用父类的打印函数

    //赋值兼容性原则 遇到 子类和父类同名函数
    p = &c1;
    p->print(); // 调用的还是父类的打印函数

    // 引用
    Parent& myp = c1; // 调用的还是父类的打印函数
    myp.print();
    */

    // 指针
    toPrint1(&p1);
    toPrint1(&c1); // 调用的还是父类的打印函数

    // 引用
    toPrint2(p1);
    toPrint2(c1); // 调用的还是父类的打印函数

    /* 输出结果:
    父类 a: 0
    父类 a: 0
    父类 a: 0
    父类 a: 0
    */
    system("pause");
}

// 多态 demo
class Parent01 {
public:
    Parent01(int a = 0) {
        this->a = a;
    }
    // 添加 virtual 多态 告知C++编译器 动态链接编译
    virtual void print() {
        cout << "父类 a: " << a << endl;
    }
protected:
private:
    int a;
};

class Child01 : public Parent01 {
public:
    Child01(int b = 0) {
        this->b = b;
    }
    void print() {
        cout << "子类 b: " << b << endl;
    }
protected:
private:
    int b;
};

// 要执行子类的print()函数,需要在父类的print()函数前,添加virtual,告知C++编译器 动态链接编译
void toPrint1(Parent01* p) {
    p->print();
}

void toPrint2(Parent01& p) {
    p.print();
}

// 面向对象新需求:
// 如果传入父类对象,执行父类的print函数
// 如果传入子类对象,执行子类的print函数
// 这个功能的需求就是多态
// 需要在父类的print()函数前,添加virtual

void main() {
    Parent01 p1;
    Child01 c1;

    // 指针
    toPrint1(&p1);
    toPrint1(&c1); // 调用的子类的打印函数

    // 引用
    toPrint2(p1);
    toPrint2(c1); // 调用的是子类的打印函数

    /* 输出结果
    父类 a: 0
    子类 b: 0
    父类 a: 0
    子类 b: 0
    */
    system("pause");
}

你可能感兴趣的:(C和C++,c++,开发语言,算法)