C++程序设计(八)—— 多态性和虚函数

本文详细介绍了C++中的多态性和虚函数,包括静态和动态联编、虚函数的定义与实现多态性的条件、构造函数与析构函数中的虚函数调用,以及纯虚函数和抽象类的应用。通过示例展示了如何利用虚函数实现运行时的多态性。
摘要由CSDN通过智能技术生成

一、多态性

        静态联编所支持的多态性称为编译时的多态性,当调用重载函数时,编译器可以根据调用时所使用的实参在编译时就确定应该调用哪个函数;动态联编所支持的多态性称为运行时的多态性,这由虚函数来支持。虚函数类似于重载函数,但与重载函数的实现策略不同,即对虚函数的调用使用动态联编。

1、静态联编中的赋值兼容性及名字支配规律

        派生一个类的原因并非总是为了添加新的数据成员或成员函数,有时是为了重新定义基类的成员函数。先看一个示例如下:

const double PI = 3.14159;
class Point {
private:
	double x, y;
public:
	Point(double a, double b) :
			x(a), y(b) {
	}
	double area() {
		return 0;
	}
};

class Circle: public Point {
private:
	double radius;
public:
	Circle(double a, double b, double c) :Point(a, b) {
		this->radius = c;
	}
	double area() {
		return PI * radius * radius;
	}
};
#include "Example1.h"
void example1();

int main() {
	example1();
	return 0;
}

void example1() {
	Point a(10.5, 12.3);
	cout << a.area() << endl; //0 名字支配规律决定它们只调用自己的area()函数
	Circle c(10.5, 12.3, 13.5);
	cout << c.area() << endl; //572.555 同上
	Point *p1 = &c;
	cout << p1->area() << endl; //0 根据赋值兼容规则,Point类的指针指向的是基类Point的area()
	Point &p2 = c;
	cout << p2.area() << endl; //0 根据赋值兼容规则,Point类的引用跟指针一样
}

         对象的内存地址空间中只包含数据成员,并不存储有关成员函数的信息,这些成员函数的地址翻译过程与其对象的内存地址无关,编译器只根据数据类型来翻译成员函数的地址并判断其调用的合法性,这是由静态联编决定的。

        声明的基类指针只能指向基类,派生类指针只能指向派生类,它们的原始类型决定它们只能调用各自的同名函数,除非派生类没有基类的同名函数,派生类的指针才根据继承调用基类的成员函数。

2、动态联编的多态性

        如果让编译器进行动态联编,这就需要使用到关键字virtual来声明虚函数。当编译系统编译含有虚函数的类时,将为它建立一个虚函数表,表中的每一个元素都指向一个虚函数的地址。此外,编译器也为类增加一个数据成员,这个数据成员是一个指向该虚函数表的指针,通常称为vptr。

        虚函数的地址翻译取决于对象的内存地址,编译器为含有虚函数的对象首先建立一个入口地址,这个地址用来存放指向虚函数表的指针vptr,然后按照类中虚函数的声明次序,一一填入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值