[C++]学习笔记9:多态性与虚函数

1.多态性的概念

多态性:向不同的对象发送同一个消息,不同的对象在接受时,会产生不同的行为

支持多态:面向对象:C++、java
不支持多态:基于对象的:VB、Ada

多态的两种情况
静态多态:在程序编译时就能决定调用哪个函数

实现:函数的重载(包含运算符重载)

动态多态:在程序运行过程中才能决定调用的对象成员

实现:虚函数(virtual function)

2.虚函数

构造函数不能为虚函数。
基类的析构函数应该为虚函数。
友元函数不能为虚,因为友元函数不是类成员,只有类成员才能是虚函数。
如果派生类没有重定义函数,则会使用基类版本。
重新定义继承的方法若和基类的方法不同(协变除外),会将基类方法隐藏;如果基类声明方法被重载,则派生类也需要对重载的方法重新定义,否则调用的还是基类的方法。

声明方法:virtual 函数类型 函数名(){}

如下面程序,

#include<iostream>
using namespace std;
class point{
	protected:
		float x;
		float y;
	public:
		point(int a,int b){
			x=a;
			y=b;
		}
		void show();
}; 

void point::show(){
	cout<<x*y<<endl;
}

class line:public point{
	protected:
		float z; 
	public:
		line(int a,int b,int c):point(a,b){
			z=c;
		}
		void show();
};

void line::show(){
	cout<<x*y*z<<endl;
}

int main(){
	point s1(2,2);
	line s2(2,2,2);
	point *p;
	p=&s1;
	p->show();
	
	p=&s2;
	p->show();
	
	return 0;
}
4
4

--------------------------------
Process exited after 0.206 seconds with return value 0
请按任意键继续. . .


当定义一个point类的指针对象后,将一个line类对象赋值给它,
当后者调用show函数时,调用的却是基类的show函数,
那么,如何解决这种问题,使p也能够调用子类的同名函数呢?

这里就用到了虚函数!

#include<iostream>
using namespace std;
class point{
	protected:
		float x;
		float y;
	public:
		point(int a,int b){
			x=a;
			y=b;
		}
		virtual void show();  //此处将show函数定义为了虚函数
}; 

void point::show(){
	cout<<x*y<<endl;
}

class line:public point{
	protected:
		float z; 
	public:
		line(int a,int b,int c):point(a,b){
			z=c;
		}
		void show();
};

void line::show(){
	cout<<x*y*z<<endl;
}

int main(){
	point s1(2,2);
	line s2(2,2,2);
	point *p;
	p=&s1;
	p->show();
	
	p=&s2;
	p->show();
	
	return 0;
}
4
8

--------------------------------
Process exited after 0.2267 seconds with return value 0
请按任意键继续. . .

从上面可以看到,当show函数被声明为虚函数后,当point类指针p被line类对象赋值后,就可调用其show函数,而不是基类point的show函数!

3.纯虚函数

非基类本身需求,而是考虑派生类需要而定义的空函数,其函数内容将在派生类中定义
定义方法:

声明一个虚函数,并将其赋值为0
格式: virtual 函数类型 函数名(参数列表) =0;
例:virtual float area() const =0;

几点说明:
纯虚函数没有函数体,也就没有“{ }”;
函数后面的“=0”不是表示返回值为0,而是纯虚函数的定义方式;
纯虚函数是用语句声明的,后面必须有分号结尾
纯虚函数不能被调用。只有在派生类中定义后,才能够被调用

纯虚函数的作用:确立多态性的起点
在这里插入图片描述

4.抽象类

不用来定义对象而只作为一种基本类型用作继承的类
抽象类(abstract class)或抽象基类

凡是包含纯虚函数的类都是抽象类
纯虚函数不能被调用,因而包含纯虚函数的类,无法建立对应的对象
如果一个派生类,未能对其基类中所有的纯虚函数进行定义,则该派生类仍然是抽象类。

#include <iostream>
#define PI 3.14
using namespace std;
class Calculate{  //此类为抽象基类,只定义虚函数确定方向,函数实现由子类完成
	virtual double getPerimeter() = 0;
	virtual double getArea() = 0;
	virtual double getCircleArea() = 0;
};
 
class BaseData: public Calculate{
	private:
		double bottom;
		double height;
		double radius;
	public:
		BaseData(double a, double b, double c):bottom(a),height(b),radius(c){}
		double getPerimeter(){
			return 2 * (bottom + height);
		}
		double getArea(){
			return bottom * height;
		}
		double getCircleArea(){
			return PI * radius * radius;
		}
};
 
int main(){
	double a, b, c;
	cin>>a>>b>>c;
	BaseData* baseData = new BaseData(a,b,c);
	cout<<baseData->getPerimeter()<<endl;
	cout<<baseData->getArea()<<endl;
	cout<<baseData->getCircleArea()<<endl;
	delete baseData;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值