千家信息网

C++如何实现同名覆盖、函数重写与多态

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章给大家分享的是有关C++如何实现同名覆盖、函数重写与多态的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。同名覆盖#includeusing namespace std
千家信息网最后更新 2025年01月18日C++如何实现同名覆盖、函数重写与多态

这篇文章给大家分享的是有关C++如何实现同名覆盖、函数重写与多态的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

同名覆盖

#includeusing namespace std;class Base{public:    int m_data;    Base():m_data(1)//父类初始化为1    {  }};class Derived : public Base{public:    int m_data;    Derived():m_data(2)//子类初始化为2    {  }};int main(){    Derived d;    //父类的m_data被隐藏了,但仍存在,可以通过::符访问    cout<<"base data: "<

运行结果

base data: 1
derived data: 2
8

说明父类和子类是允许存在同名成员的,只不过父类的成员被编译器隐藏了,正常访问得到的是子类成员的值。

那么如果是函数同名呢?

函数重写

函数重写是同名覆盖的一种特殊情况,即子类中重新实现父类中的同名函数,属于同名覆盖

#includeusing namespace std;class Base{public:    void print()    {        cout<<"Base class"<

运行结果

Base class
Derived class

如果调用how_to_print函数,期望传入父类对象时调用父类打印函数,传入子类对象时调用子类对象函数

void how_to_print(Base* p){    p->print();//期望根据对象选择相应函数,不能实现}int main(){    Base b;    Derived d;    how_to_print(&b);    how_to_print(&d);    return 0;}

结果却是都打印Base class

Base class
Base class

结果没有符合预期,分析:

1.传入父类对象b的地址时,父类指针指向父类对象,打印正常;

2.传入子类对象d的地址时,父类指针指向子类对象,此时由于赋值兼容性(子类对象可以当作父类对象使用),子类对象退化为父类对象(父类指针只能访问父类成员),编译器认为父类指针指向的是父类对象,因此最终调用了父类的打印函数

以上结果是合理的,却没有符合预期的目的,这也是函数重写带来的问题。如果不能实现以上目的,函数重写是没有意义的,那么如何实现父类指针(引用)指向:

  • 父类对象,调用父类函数

  • 子类对象,调用重写函数

实际上以上行为就是多态

多态

所谓多态,即同样的调用语句,在实际运行时存在不同的表现状态,依据则是对象的类型不同

要实现上文中函数重写的多态,需要引入virtual关键字,C++原生支持多态

  • 通过使用virtual关键字对多态进行支持

  • 被virtual声明的函数被重写后具有多态特性

  • 被virtual声明的函数叫做虚函数

在父类函数print声明前添加virtual关键字,print函数成为虚函数,子类重写的函数也将自动变成虚函数,这样就可以实现多态

class Base{public:    virtual void print()//加virtual变成了虚函数    {        cout<<"Base class"<

运行结果

Base class
Derived class

多态的意义:

在程序运行过程中展现出动态的特性函数重写必须多态实现,否则没有意义多态是面向对象组件化程序设计的基础特性

感谢各位的阅读!关于"C++如何实现同名覆盖、函数重写与多态"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

0