C++ 多态性与虚函数

本文介绍了C++中的多态性,包括静态多态性和动态多态性,重点讲解了虚函数的概念、作用、定义方式以及与函数重载的区别。此外,还讨论了虚函数的使用要求,强调了虚析构函数的重要性,以及纯虚函数和抽象类在实现多态性中的角色。

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

1.多态性

多态性:对同一的消息,不同对象有不同的响应方式。

多态性分两种:静态多态性动态多态性
静态多态性 是通过函数的重载实现的,在程序编译时系统就能决定要调用的是哪个函数,也称编译时的多态性。
动态多态性 是通过虚函数实现的,在程序运行过程中才动态地确定操作所针对的对象。

  • 坐公交车前确定了路线就好比静态多态性,而临时决定路线就好比动态多态性。

2.虚函数

在类的继承层次结构中,若派生类和基类存在成员函数相同的情况,编译系统按照同名覆盖的原则决定调用的对象。

虚函数:在基类声明函数是虚拟的,并不是实际存在的函数,然后在派生类中才正式定义此函数。

虚函数的作用是:允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。(非虚函数,指向基类的指针可以指向派生类,但只能引用派生类中继承的基类成员

(1)虚函数定义

定义虚函数:
class Student
{public:
	virtual void display();
	...
}

class Student1: public Student
{public:
	void display();
	...
}

在main函数中:

Student stud, *p;
Student1 stud1;
p = &stud;
p->display(); // 基类的display
p = &stud1;
p->display(); // 派生类的display

// 如果基类display不是虚函数,那么上面两次调用的display均为基类的display。

这就是 多态性:对同一的消息,不同对象有不同的响应方式。

注意
<1>在类体中声明成员函数为virtual,在类体外定义时不必再加virtual;
<2>在派生类中重新定义此函数,函数名、函数类型、函数参数个数和类型,必须与基类的虚函数相同,根据派生类的需要重新定义函数体;
<3>定义一个指向基类对象的指针变量,并使它指向同一类组中需要调用该函数的对象;
<4>通过该指针调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。

重载与虚函数的区别:
<1>函数重载处理的是同一层次上的同名函数问题,而 虚函数 是处理 不同派生层次上 的同名函数问题;前者是横向重载,后者是纵向重载;
<2>同一类组的 虚函数的首部是相同的 ,而函数重载时函数的首部是不同的(参数个数或类型不同)。

(2)关联
确定调用的具体对象的过程称为关联
编译时确定的关联称为静态关联(或早期关联),运行阶段时称为动态关联(滞后关联)。

(3)虚函数的使用要求
<1>只能是声明 类的成员函数为虚函数,类外的普通函数不行。因为虚函数的作用是允许在派生类中对基类的虚函数重新定义;
<2>一个成员函数被声明为虚函数之后,在同一类族中就 不能再定义一个非virtual 但与该虚函数首部相同的 同名函数

什么情况下考虑虚函数:
<1>首先看成员函数所在类是否为基类,再看该成员函数在派生类中是否会被修改,若两者都是,则虚之;
<2>如果成员函数在派生类中不被修改或根本用不到,则不虚之;
<3>该成员函数通过基类指针去访问,则虚之;
<4>声明虚函数,但不定义结构体,留着派生类定义。

注意:虚函数有空间开销,系统为含虚函数的类创建一个虚函数表,它是指针数组,存放每个虚函数的入口地址。

(4)虚析构函数
在程序中,最好把基类的析构函数声明为虚函数,这将使所有派生类的析构函数自动成为虚函数。

3.纯虚函数与抽象类

(1)纯虚函数
有时基类中的虚函数,并不是积累本身需要,而是 考虑到派生类的需要,实现多态性。在基类中预留,在派生类中定义。

一般形式:
virtual 函数类型 函数名(参数列表)=0virtual void display()=0;

注意
<1>纯虚函数没有函数体;
<2>“=0”是告诉编译系统,这是个纯虚函数;
<3>纯虚函数只有函数名不具备函数功能,不能被调用;
<4>如果派生类没有对基类的纯虚函数做定义,则该纯虚函数在派生类中仍为纯虚函数。

(2)抽象类
不用来定义对象只用作继承的类,称为抽象类。凡是包含纯虚函数的类都是抽象类。因为纯虚函数无法被调用,所以包含纯虚函数的类不能创建对象。

注意:虽然抽象类不能实例化,但是可以定义指向抽象类数据的指针变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值