栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

4.7 多态

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

4.7 多态

4.7 多态

4.7.1 多态的基本概念

4.7.2 纯虚函数和抽象类

4.7.3 虚析构和纯虚析构


4.7 多态

4.7.1 多态的基本概念

多态是C++面向对象三大特性之一

多态分为两类

  • 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名

  • 动态多态: 派生类和虚函数实现运行时多态

静态多态和动态多态区别:

  • 静态多态的函数地址早绑定 - 编译阶段确定函数地址

  • 动态多态的函数地址晚绑定 - 运行阶段确定函数地址

多态满足条件:

  • 有继承关系

  • 派生类重写基类中的虚函数

多态使用条件

  • 基类指针或引用指向派生类对象

重写:函数返回值类型 函数名 参数列表 完全一致称为重写

示例

#include  
#include 
#include 
#include 
using namespace std;
​
class person{
    public:
        void show(){
            cout<<"是一个人"< 

虚函数实现

#include  
#include 
#include 
#include 
using namespace std;
​
class person{
    public:
        //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了
        virtual void show(){
            cout<<"是一个人"< 

多态的优点:

  • 代码组织结构清晰

  • 可读性强

  • 利于前期和后期的扩展以及维护

示例

#include  
#include 
#include 
#include 
using namespace std;
​
//抽象计算器类
//多态优点:代码组织结构清晰,可读性强,利于前期和后期的扩展以及维护
class base{
    public:
        int x,y;
        
        virtual int calculate(){
            return 0;
        }
};
​
//加法计算器
class add:public base{
    public:
        int calculate(){
            return x+y;
        }
};
​
//减法计算器
class sub:public base{
    public:
        int calculate(){
            return x-y;
        }
};
​
//乘法计算器
class mul:public base{
    public:
        int calculate(){
            return x*y;
        }
};
​
int main(){
    
    //基类指针指向派生类对象的加法计算器
    add a;
    base *b1=&a;
    b1->x=10;
    b1->y=20;
    cout<calculate()<x=10;
    b3->y=20;
    cout<calculate()< 

总结:C++开发提倡利用多态设计程序架构,因为多态优点很多


4.7.2 纯虚函数和抽象类

在多态中,通常基类中虚函数的实现是毫无意义的,主要都是调用派生类重写的内容,可以将虚函数改为纯虚函数

纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ;

当类中有了纯虚函数,这个类也称为抽象类(只要有一个函数是纯虚函数,就是抽象类)

抽象类特点:

  • 无法实例化对象

  • 派生类必须重写抽象类中的纯虚函数,否则也属于抽象类

示例:

#include  
#include 
#include 
#include 
using namespace std;
​
class point{
    public:
        int x,y;
        
        //纯虚函数
        //类中只要有一个纯虚函数就称为抽象类
        virtual void show()=0;
};
​
class point_son_1:public point{
    public:
        
};
​
class point_son_2:public point{
    public:
        void show(){
            cout<x=10;
    p3->y=20;
    p3->show();
    
} 
​
int main(){
    
    test01();
    
    test02();
    
    return 0;
    
}

4.7.3 虚析构和纯虚析构

多态使用时,如果派生类中有属性开辟到堆区,那么基类指针在释放时无法调用到派生类的析构代码

解决方式:将基类中的析构函数改为虚析构或者纯虚析构

虚析构和纯虚析构共性:

  • 可以解决基类指针释放派生类对象

  • 都需要有具体的函数实现

虚析构和纯虚析构区别:

  • 如果是纯虚析构,该类属于抽象类,无法实例化对象

虚析构语法:

virtual ~类名(){}

纯虚析构语法:

virtual ~类名() = 0;

类名::~类名(){}

示例:

#include  
#include 
#include 
#include 
using namespace std;
​
class person{
    public:
        person(){
            cout<<"person的构造函数调用"<show();
    
    //通过基类指针去释放,会导致派生类对象可能清理不干净,造成内存泄漏
    delete p;
    
    return 0;
    
}

解决方法1 将基类函数的析构函数改为虚析构

#include  
#include 
#include 
#include 
using namespace std;
​
class person{
    public:
        person(){
            cout<<"person的构造函数调用"<show();
    
    delete p;
    
    return 0;
    
}

解决方法2 利用纯虚析构函数的方法

#include  
#include 
#include 
#include 
using namespace std;
​
class person{
    public:
        person(){
            cout<<"person的构造函数调用"<show();
    
    delete p;
    
    return 0;
    
}

总结:

1. 虚析构或纯虚析构就是用来解决通过基类指针释放派生类对象

2. 如果派生类中没有堆区数据,可以不写为虚析构或纯虚析构

3. 拥有纯虚析构函数的类也属于抽象类

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/892887.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号