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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的多是指在基类和派生类之间,通过虚函数实现的动绑定机制。通过多性,可以在基类的指针或引用上调用派生类的函数,实现动绑定和运行时多。 在C++中,要实现多性,需要使用以下两个关键字: 1. virtual:在基类中声明虚函数,表示该函数可以被派生类重写。 2. override:在派生类中重写虚函数时,使用override关键字,表示该函数是对基类虚函数的覆盖。 下面是一个简单的示例: ```c++ #include <iostream> using namespace std; class Shape { protected: int width; int height; public: virtual int area() { cout << "Parent class area :" << endl; return 0; } }; class Rectangle: public Shape { public: int area () override { cout << "Rectangle class area :" << endl; return (width * height); } }; class Triangle: public Shape { public: int area () override { cout << "Triangle class area :" << endl; return (width * height / 2); } }; int main() { Shape *shape; Rectangle rec; Triangle tri; // 矩形对象的地址赋值给指向基类的指针 shape = &rec; // 调用矩形的求面积函数 area shape->area(); // 三角形对象的地址赋值给指向基类的指针 shape = &tri; // 调用三角形的求面积函数 area shape->area(); return 0; } ``` 在上面的示例中,定义了一个Shape基类和两个派生类Rectangle和Triangle。在Shape类中声明了一个虚函数area(),在Rectangle和Triangle类中重写了该函数。在main函数中,分别创建了Rectangle和Triangle对象,并将它们的地址赋值给基类Shape的指针shape。通过shape指针调用area()函数时,会根据对象的实际类型,动地调用相应的派生类函数,实现了多性和动绑定机制。 总的来说,C++中的多性是一种重要的面向对象特性,可以提高程序的可扩展性和可维护性,应用广泛。在实际的开发中,多性通常与其他面向对象的技术和设计模式相结合,从而实现更加复杂的功能和需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值