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

这篇博客探讨了C++中的多态性,通过一个实例展示了如何在没有使用`virtual`关键字时,子类对象调用同名函数会默认执行父类的函数。文章解释了这种现象产生的原因,即静态链接编译。然后引入了`virtual`关键字来实现动态链接编译,实现了多态性,使得在调用子类对象的函数时能够正确执行子类重写的函数。最后,通过两个示例`toPrint1`和`toPrint2`,演示了在使用指针和引用时,如何利用多态性实现不同行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
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");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值