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


    类型转换规则

    类定义的指针可以指向子类对象;
    在这里插入图片描述
    在这里插入图片描述
    指针会误以为,他们指向的对象是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 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    shape.cpp

    #include "shape.h"
    #include 
    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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    shape.h

    #ifndef SHAPE_H
    #define SHAPE_H
    #include 
    #include 
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    circle.cpp

    #include "circle.h"
    #include "shape.h"
    #include 
    	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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    circle.h

    #ifndef CIRCLE_H
    #define CIRCLE_H
    #include 
    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    rectangle.cpp

    #include "rectangle.h"
    #include "shape.h"
    #include 
    
    	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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    rectangle.h

    #ifndef RECTANGLE_H
    #define RECTANGLE_H
    #include 
    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    roundrectangle.cpp

    #include "roundrectangle.h"
    #include "rectangle.h"
    #include"shape.h"
    #include 
    	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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    roundrectangle.h

    #ifndef ROUNDRECTANGLE_H
    #define ROUNDRECTANGLE_H
    #include 
    #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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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

    #include "shape.h"
    #include "circle.h"
    #include "rectangle.h"
    #include "roundrectangle.h" 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    ImportError: cannot import name ‘Mapping‘ from ‘collections‘
    图像处理ASIC设计方法 笔记10 插值算法的流水线架构
    基于FPGA的DDS任意波形输出
    CalBioreagents 绵羊抗α-2-HS糖蛋白 亲和纯化说明
    2024杭州人工智能展会(世亚智博会)一场人工智能领域的视觉盛宴
    C++实现:实现一个函数,接受一个n x n的矩阵并返回其行列式的值 某知名上市公司笔试题
    最详细STM32,cubeMX 定时器
    2022最新IntellJ IDEA诺依开发部署文档
    Java基础知识篇之类的基本概念
    网络简答题带答案
  • 原文地址:https://blog.csdn.net/weixin_45636780/article/details/133763584