多态

本文介绍了C++中多态的相关知识。多态指不同类对象对同一消息有不同反应,能增加程序灵活性。多态基本要求是赋值兼容,有三种形式,常用派生类地址赋给基类指针。达成多态需父类有虚函数、子类重写虚函数、通过父类指针调用操作。还介绍了纯虚函数和虚函数继承。

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

C++中所谓的多态是指由继承产生相关的不同的类,其对象会对同一消息做出不同的反应

比如使用绘图软件时选择不同的图形,执行同一个托动作就可以绘制不同的图形

多态是面向对象的一个重要特征,能增加程序的灵活性,可以减轻系统的维护工作量

多态的基本要求:赋值兼容

赋值兼容规则是指,在需要基类的任何地方,都可以使用公有派生类来进行替代。

只有在公有派生类中才有赋值兼容,赋值兼容是一种默认行为,不需要任何的显示的转化步骤

一般有三种赋值兼容:

1.派生类赋给基类
2.派生类赋给基类的引用
3.派生类地址赋给基类的指针,多态中最常用的就是这个

class A{
public:
     ......
}

class B:public A{
public:
     ......
{

int main(){

A a;
B b;
a = b;  //派生类赋给基类
A &ra = b; //派生类赋给基类的引用
A *pa = &b; //派生类地址赋给基类的指针,多态中最常用的就是这个

}

其中1,2不常用,多态中最常用的是派生类地址赋给基类的指针

多态的达成条件

多态一般有三个条件:

1.父类中有虚函数,即公共接口

2.子类重写(override)父类中的虚函数

3.通过已被子类对象赋值的父类指针,调用相关的操作

格式:

class base{
   virtual type function()...
}

前面提到过拖动画出不同的图形,这就是典型的多态,我们可以简单地来实现一下:

#include <iostream>
using namespace std;

//多态实例
class shape {
public:
	shape(int x, int y) :_x(x), _y(y) {}

	virtual void draw();  //定义虚函数

protected:
	int _x;
	int _y;
};
void shape::draw()
{
	cout << "draw shape from: " << _x << "," << _y << endl;
}


class circle :public shape {
public:
	circle(int x, int y, int r) :shape(x, y), _radius(r) {}
	void draw() override;  //虚函数重写,格式必须同名同参同返回
protected:
	int _radius;
};

void circle::draw()
{
	cout << "draw shape from: " << _x << "," << _y << "," << _radius << endl;

	cout << "shape" << this << endl;
	cout << typeid(this).name() << endl;
}

class Rect : public shape {
public:
	Rect(int x,int y,int w,int h):shape(x,y){
		_width = w;
		_height = h;
	}
	void draw() override;  //虚函数重写

protected:
	int _width;
	int _height;
};

void Rect::draw()
{
	cout << "draw shape from: " << _x << "," << _y << "," << _width <<","<<_height<<endl;
	cout << "shape" << this << endl;
	cout << typeid(this).name() << endl;
}

int main() {

	circle cr(3, 4, 5);
	cr.draw();

	cout << endl << endl;
	shape* PFcr = &cr;
	PFcr->draw();   //一个接口,呈现出不同的行为,称为多态

	Rect rc(7, 8, 9, 10);
	PFcr = &rc;
	PFcr->draw();

	system("PAUSE");
}

纯虚函数

纯虚函数,是一类没有实现体,切被初始化为0的函数

1纯虚函数只有声明,没有实现,被初始化为"0"

2含有纯虚函数的类,被称为抽象基类,不可被实例化,即不能创建对象,存在的意义就是被继承,提供公共接口

3如果一个类中声明了纯虚函数,而派生类中没有该函数的定义,则该虚函数在派生类中仍为虚函数,派生类仍未虚基类

4虚基类是无法实例化的(即无法创建对象)

class virbase{
   virtual type function = 0;
}

我们可以修改刚刚的图形继承案例,将draw函数改成纯虚函数,shape类就成了抽象基类,子类则需要对其进行重写操作

补充:虚函数的继承

多重继承中,孙子类可以覆写子孙类中的接口,比如下面这个例子中,子类没有重写父类的抽象函数,而是由孙子类进行了重写

这是允许的

class A {
public:
	virtual void func() = 0;
};

class B :public A {
public:
	
};

class C :public B {
public:
	void func() override;  //孙子类重写祖先类虚函数
};

void C::func()
{
	cout << "C::" << endl;
}

int main() {

	C c;
	A* pa = &c;
	pa->func();

	system("PAUSE");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值