C++类和对象-多态->多态的基本语法、多态的原理剖析、纯虚函数和抽象类、虚析构和纯虚析构

本文主要是介绍C++类和对象-多态->多态的基本语法、多态的原理剖析、纯虚函数和抽象类、虚析构和纯虚析构,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#include<iostream>
using namespace std;

//多态
//动物类
class Animal
{
public:
    //Speak函数就是虚函数
    //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。
    virtual void speak()
    {
        cout << "动物在说话" << endl;
    }
};
//猫类
class Cat :public Animal
{
public:
    //重写 函数返回值类型  函数名  参数列表  完全相同
    void speak()
    {
        cout << "小猫在说话" << endl;
    }
};
//狗类
class Dog :public Animal
{
public:

    void speak()
    {
        cout << "小狗在说话" << endl;
    }

};
//我们希望传入什么对象,那么就调用什么对象的函数
//如果函数地址在编译阶段就能确定,那么静态联编
//如果函数地址在运行阶段才能确定,就是动态联编

//执行说话的函数
//地址早绑定  在编译阶段确定函数地址
//如果想执行让猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定

//动态多态满足条件
//1.有继承关系
//2.子类重写父类的虚函数

//动态多态使用
//父类的指针或者引用  执向子类对象

void DoSpeak(Animal & animal)
{
    animal.speak();
}
//
//多态满足条件:
//1、有继承关系
//2、子类重写父类中的虚函数
//多态使用:
//父类指针或引用指向子类对象

void test01()
{
    Cat cat;
    DoSpeak(cat);


    Dog dog;
    DoSpeak(dog);
}


int main() {

    test01();

    system("pause");

    return 0;
}

总结:

多态满足条件

* 有继承关系
* 子类重写父类中的虚函数

多态使用条件

* 父类指针或引用指向子类对象

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

#include<iostream>
using namespace std;

//纯虚函数和抽象类
class Base
{
public:
    //纯虚函数
    //类中只要有一个纯虚函数就称为抽象类
    //抽象类特点:
    //1.无法实例化对象
    //2.抽象类的子类 必须重写父类中的纯虚函数,否则也属于抽象类
    virtual void func() = 0;
};

class Son :public Base
{
public:
    virtual void func()
    {
        cout << "func调用" << endl;
    };
};

void test01()
{
    //Base b;   //抽象类无法实例化对象
    //new Base; //抽象类无法实例化对象
    //Son s;//子类必须重写父类中的纯虚函数,否则无法实例化对象
    Base * base = new Son;
    base->func();
    delete base;//记得销毁
}

int main() {

    test01();

    system("pause");

    return 0;
}

#include<iostream>
using namespace std;
#include<string>

//虚析构和纯虚析构
class Animal
{
public:

    Animal()
    {
        cout << "Animal 构造函数调用!" << endl;
    }
    //纯虚函数
    virtual void Speak() = 0;

    //利用虚析构可以解决 父类指针释放子类对象时不干净的问题
    //析构函数加上virtual关键字,变成虚析构函数
    //virtual ~Animal()
    //{
    //    cout << "Animal虚析构函数调用!" << endl;
    //}

    //纯虚析构  需要声明也需要实现
    //有了纯虚析构 之后,这个类也属于抽象类,无法实例化对象
    virtual ~Animal() = 0;
};

Animal::~Animal()
{
    cout << "Animal 纯虚析构函数调用!" << endl;
}

//和包含普通纯虚函数的类一样,包含了纯虚析构函数的类也是一个抽象类。不能够被实例化。

class Cat : public Animal
{
public:
    Cat(string name)
    {
        cout << "Cat构造函数调用!" << endl;
        m_Name = new string(name);
    }
    virtual void Speak()
    {
        cout << *m_Name <<  "小猫在说话!" << endl;
    }
    ~Cat()
    {
        cout << "Cat析构函数调用!" << endl;
        if (this->m_Name != NULL)
        {
            delete m_Name;
            m_Name = NULL;
        }
    }

public:
    string * m_Name;
};

void test01()
{
    Animal * animal = new Cat("Tom");
    animal->Speak();

    //通过父类指针去释放,会导致子类对象可能清理不干净,造成内存泄漏
    //怎么解决?给基类增加一个虚析构函数
    //虚析构函数就是用来解决通过父类指针释放子类对象

    //父类指针在析构时候 不会调用子类中析构函数,导致子类如果有堆区属性,出现内存泄露
    delete animal;
}

int main() {

    test01();

    system("pause");

    return 0;
}

总结:

​    1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象

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

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

这篇关于C++类和对象-多态->多态的基本语法、多态的原理剖析、纯虚函数和抽象类、虚析构和纯虚析构的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717141

相关文章

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Python ORM神器之SQLAlchemy基本使用完全指南

《PythonORM神器之SQLAlchemy基本使用完全指南》SQLAlchemy是Python主流ORM框架,通过对象化方式简化数据库操作,支持多数据库,提供引擎、会话、模型等核心组件,实现事务... 目录一、什么是SQLAlchemy?二、安装SQLAlchemy三、核心概念1. Engine(引擎)

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C