极简c++(8)抽象类与多态

本文介绍了C++中的类型转换、虚函数、多态(包括动态绑定)、抽象类和纯虚函数的概念,并通过实例展示了如何在shape、circle、rectangle和roundrectangle类中实现这些特性。通过main.cpp中的代码,演示了如何使用基类指针指向派生类对象以及如何正确处理析构函数和虚函数的使用。

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

类型转换规则

父类定义的指针可以指向子类对象;
在这里插入图片描述
在这里插入图片描述
指针会误以为,他们指向的对象是Base1类型,导致错误;

虚函数定义

在这里插入图片描述
在这里插入图片描述

多态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如何实现多态:
1.创建类的继承关系图
2.所以类对象都可以调用的这个函数
3.创建父类指针数组
4.子类的地址赋给父类指针
5.指针调用虚函数

动态绑定

和多态其实是一个概念
在这里插入图片描述
动态绑定我们是无法在运行之前,事先知道运行的结果是不知道的;
在这里插入图片描述
不仅是指针,引用也可以!
在这里插入图片描述
指针和引用可以,但最后一种情况无法实现多态

虚析构函数

在这里插入图片描述

在这里插入图片描述
创建的时候是先创建base再创建derived的;这个时候,不加virtual 的话会导致,只delete了base,但没有delete掉derived;
建议所有析构函数都加virtual
只有用new去创建的时候,才有可能出现这种错误。

纯虚函数与抽象类

在这里插入图片描述
对于暂时无法实现的函数,我们可以定义为纯虚函数,留给派生类去实现;
定义了纯虚函数的类叫抽象类;
抽象类只能作为基类来使用;
构造函数不能是虚函数,析构函数可以是虚函数;

为什么需要抽象类

在这里插入图片描述
在这里插入图片描述

抽象类的特点

在这里插入图片描述

作业

在这里插入图片描述
main.cpp

#include "shape.h"
#include "circle.h"
#include "rectangle.h"
#include "roundrectangle.h" 
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(void) {
	shape *ptrShape[6];
	circle circle1;
	circle circle2("red",2);
	Rectangle Rectangle1,Rectangle2("green",2,3);
	RoundRectangle RoundRectangle1,RoundRectangle2("yelow",2,3,1);
	ptrShape[0] = &circle1;
	ptrShape[1] = &circle2;
	ptrShape[2] = &Rectangle1;
	ptrShape[3] = &Rectangle2;
	ptrShape[4] = &RoundRectangle1;
	ptrShape[5] = &RoundRectangle2;
	
//	ptrShape[0] = new circle;
//	ptrShape[1] = new Rectangle;
//	ptrShape[2] = new RoundRectangle;
//	ptrShape[3] = new circle("red",2);
//	ptrShape[4] = new Rectangle("red",2,3);
//	ptrShape[5] = new RoundRectangle("red",2,3,1);
	for(int i=0;i<6;i++){
		cout<<"该图形面积为:"<<ptrShape[i]->getArea()<<endl;
	}
	return 0;
}

shape.cpp

#include "shape.h"
#include <iostream>
using namespace std;		
	shape::shape():color("white"){
		cout<<"无参创建shape"<<endl;
	}
	shape::shape(string color){
		this->color = color;
		cout<<"有参创建shape"<<endl;
	}
	shape::~shape(){
		cout<<"消亡shape"<<endl;
	}
	string shape::getColor(){
		return this->color;
	}
	void shape::setColor(char color){
		this->color = color;
	}
	void shape::display(){
		cout<<"color:"<<getColor()<<endl;
	}

shape.h

#ifndef SHAPE_H
#define SHAPE_H
#include <string>
#include <iostream>
using namespace std;
class shape{
	private:
		string color;
	public:
		shape();
		shape(string color);
		virtual ~shape();			//析构函数+virtual 
		string getColor();
		void setColor(char color);
		void display();
		virtual double getArea()=0; //纯虚函数,变成抽象类 
};

#endif

circle.cpp

#include "circle.h"
#include "shape.h"
#include <iostream>
	const double pi = 3.14;
	circle::circle(){
		radius = 1;
		cout<<"无参创建circle"<<endl;
	}
	circle::circle(string color,double radius):shape(color){
		this->radius = radius;
		cout<<"有参创建circle"<<endl;
	}
	circle::~circle(){
		cout<<"消亡circle"<<endl;
	}
	double circle::getRadius(){
		return this->radius;
	}
	void circle::setradius(double radius){
		this->radius = radius;	
	}
	double circle::getArea(){
		return pi*radius*radius;
	}
	void circle::display(){
		shape::display();
		cout<<"R="<<getRadius()<<","<<"Area="<<getArea()<<endl;
	}

circle.h

#ifndef CIRCLE_H
#define CIRCLE_H
#include <string>
#include "shape.h"

class circle:public shape{
	private:
		double radius;
	public:
		circle();
		circle(string color,double radius);
		virtual ~circle();
		void setradius(double radius);
		double getRadius();
		double getArea();
		void display();
};



#endif

rectangle.cpp

#include "rectangle.h"
#include "shape.h"
#include <iostream>

	Rectangle::Rectangle(){
		width = 1;
		height = 1;
		cout<<"无参创建Rectangle"<<endl;
	}
	Rectangle::Rectangle(string color,double width,double height):shape(color){
		this->width = width;
		this->height = height;
		cout<<"有参创建Rectangle"<<endl; 
	}
	Rectangle::~Rectangle(){
		cout<<"消亡Rectangle"<<endl;
	}
	double Rectangle::getWidth(){
		return width; 
	}
	double Rectangle::getHeight(){
		return height;
	}
	void Rectangle::setWidth(double width){
		this->width = width;
	}
	void Rectangle::setHeight(double height){
		this->height = height;
	}
	double Rectangle::getArea(){
		return width*height;
	}
	void Rectangle::display(){
		shape::display();
		cout<<"width="<<getWidth()<<","<<"Height="<<getHeight()<<","<<"Area="<<getArea()<<endl;
	}

rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H
#include <string>
#include "shape.h"

class Rectangle:public shape{
	private:
		double width;
		double height;
	public:
		Rectangle();
		Rectangle(string color,double width,double height);
		virtual ~Rectangle();
		void setWidth(double width);
		void setHeight(double height);
		double getWidth();
		double getHeight();
		double getArea();
		void display();
};


#endif

roundrectangle.cpp

#include "roundrectangle.h"
#include "rectangle.h"
#include"shape.h"
#include <iostream>
	RoundRectangle::RoundRectangle(){
		this->roundRadius = 1;
		cout<<"无参创建RoundRectangle"<<endl; 
	}
	RoundRectangle::RoundRectangle(string color,double width,double height,double roundRadius):Rectangle(color,width,height){
		this->roundRadius = roundRadius;
		cout<<"有参创建RoundRectangle"<<endl;
	}
	RoundRectangle::~RoundRectangle(){
		cout<<"消亡RoundRectangle"<<endl; 
	}
	double RoundRectangle::getRoundradius(){
		return roundRadius;
	}
	void RoundRectangle::setRoundradius(double roundRadius){
		this->roundRadius = roundRadius;
	}
	double RoundRectangle::getArea(){
		return Rectangle::getWidth()*Rectangle::getHeight()+(3.14*roundRadius*roundRadius)/2;
	}
	void RoundRectangle::display(){
		shape::display();
		cout<<"width="<<Rectangle::getWidth()<<","<<"Height="<<Rectangle::getHeight()<<","<<"Area="<<getArea()<<endl;
	}

roundrectangle.h

#ifndef ROUNDRECTANGLE_H
#define ROUNDRECTANGLE_H
#include <string>
#include "rectangle.h"

class RoundRectangle:public Rectangle{
	private:
		double roundRadius;
	public:
		RoundRectangle();
		RoundRectangle(string color,double width,double height,double roundRadius);
		virtual ~RoundRectangle();
		void setRoundradius(double roundRadius);
		double getRoundradius();
		double getArea();
		void display();
};


#endif

在这里插入图片描述
(1)必须要定义,因为getArea()是纯虚函数,派生类必须补全他的函数实现,否则Circle也会变成抽象类,无法创建对象
(2)不会,因为它可以调用他的父类Rectangle类的getArea(),编译不出错,但内容是错误的
(3)可以。但
在这里插入图片描述

#include "shape.h"
#include "circle.h"
#include "rectangle.h"
#include "roundrectangle.h" 
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

double sumArea(shape* shapes[],int n){
	double sum = 0;
	for(int i = 0 ;i<n;i++){
		sum += shapes[i]->getArea();
	}
}

int main(void) {
	shape *ptrShape[6];
	circle circle1;
	circle circle2("red",2);
	Rectangle Rectangle1,Rectangle2("green",2,3);
	RoundRectangle RoundRectangle1,RoundRectangle2("yelow",2,3,1);
	ptrShape[0] = &circle1;
	ptrShape[1] = &circle2;
	ptrShape[2] = &Rectangle1;
	ptrShape[3] = &Rectangle2;
	ptrShape[4] = &RoundRectangle1;
	ptrShape[5] = &RoundRectangle2;
	
//	ptrShape[0] = new circle;
//	ptrShape[1] = new Rectangle;
//	ptrShape[2] = new RoundRectangle;
//	ptrShape[3] = new circle("red",2);
//	ptrShape[4] = new Rectangle("red",2,3);
//	ptrShape[5] = new RoundRectangle("red",2,3,1);
	for(int i=0;i<6;i++){
		cout<<"该图形面积为:"<<ptrShape[i]->getArea()<<endl;
	}
	cout<<"总面积"<<sumArea(ptrShape,6)<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值