C++运行时多态简单介绍

多态

  多态与继承时相辅相成的, 将父类定义为一个抽象类,子类可以通过继承的方式定义自己的类,这就是所谓的继承和多态,多态是在运行时编译的,且右基类指针指向子类对象,不能相反,这样基类指针可以在具体实例化的时候表现出各种各样的多态性质。也即使用什么对象来初始化基类指针所指对象,那么该基类指针指向的对象就是什么对象,这就是多态。
  构造函数不能是多态,因为虚函数需要一个虚指针vptr指向,但是这个指针是在对象调用调用构造函数时才生成的,时间顺序上不合适。同时从多态的角度考虑,虚函数主要实现运行时多态,通过基类指针的不同调用来表现多态的性质,也即子类的成员函数是由父类指针调用的,反之构造函数则是每个对象自身调用的。
  this指针存在于使用它的每个成员函数中,每个使用它的非静态成员函数隐式生成的,指向调用它的那类或者对象。
  析构函数可以是多态的,因为基类指针在多态时指向不同的成员对象,那么析构是就不能使用统一的析构函数,这就需要每个子类自己实现自己的析构函数,再由基类指针调用析构。

实例

#include<bits/stdc++.h>
using namespace std;

//动态多态的实例

//一定要注意纯虚函数和虚函数的区别
//纯虚函数中函数只有声明,没有实现。
//虚函数它用virtual修饰,同时有自己的实现,可以别继承的类重写,也即覆盖多态或者重载多态。 

class shape{
	public:
		virtual double area(){
			cout<<"我是你爸爸"<<endl;
			return 1.9;
		}
	//析构函数可以是虚函数 
	//动态多态后,父类指针可以根据指向子类的类型来实现析构多态。 
	virtual ~shape(){};
};

class circle:public shape{
	private:
		double r;
	public:
		//构造函数不能是虚函数
		//①从存储空间的角度,虚函数的调用需要一个vptr的指针,而该指针存在对象的存储空间内。
		//而对象的存储空间是在调用构造函数之后才生成的,时间顺序不对。
		//②从多态角度,多态是由父类创建对象指针,由派生类实例化具体的多态对象,这里就是典型的多态
		//而构造函数是每个函数主动调用的,而不是由父类调用的。 
		circle(double r){
			this->r=r;
		}
		virtual double area(){
			cout<<"我是小圆圈"<<endl; 
			return 3.14*r*r;
		}
		~ circle(){};
};

class rect:public shape{
	private:
		double h,w;
	public:
		rect(double h,double w){
			//每一个对象在创建时都隐式地包含一个this指针,不能引用,不可更改,不能右值 
			//this指针不能再静态成员函数中,并且一定在类成员函数中
			//它指向使用该成员函数的那个对象。
			//这里使用构造函数的对象就是rect 
			this->h=h;
			this->w=w;
		}
		virtual double area(){
			cout<<"我是小方块"<<endl; 
			return h*w;
		}
		~rect(){};
};
int main(){
	//使用基类指针指向派生类对象 
	shape *s1=new circle(2.2);
	shape *s2=new rect(3,4);
	cout<<s1->area()<<endl;
	cout<<s2->area()<<endl;
	//使用基类指针销毁派生类对象时,我们需要用到虚析构的技术 
	delete s1;
	s1=nullptr;
	delete s2;
	s2=nullptr;
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值