多态语法c++(自学笔记一)

2023-11-05

多态中的纯虚函数

使用多态时,当子类继承父类之后,一般来说对于父类只是作为提供相应的成员变量和成员函数的一个集合。

在实际项目中,如果想要修改某一部分的功能,按照以往普通的类的写法,就需要修改类中的代码,也可以说是源码,这样会显得很不方便和不安全,因此,我们只希望父类作为一个提供成员变量和成员函数的一个集合(接口?)在父类外进行实现,而父类的成员函数一般只做声明,不做实现,这也是使用多态的一个目的。

对于纯虚函数,当父类中的函数只做一个声明时,为了简化写法,就可以直接写为纯虚函数。

//纯虚函数的写法:virtual 函数返回类型 函数名() = 0

#include<iostream>
using namespace std;

class base
{
public:
	//这里创建了一个纯虚函数func()
	virtual void func() = 0;

public:

};

当类中有任何一个函数变为了纯虚函数之后,该类就会变成一个抽象类

  • 抽象类的特点:
  1. 无法实例化对象
  2. 抽象类的子类 必须要重写父类中的纯虚函数 否则也属于抽象类(重写的语法,之前已做过笔记)

完整代码:

#include<iostream>
using namespace std;

//纯虚函数和抽象类
class base
{
public:

	//纯虚函数的写法:
	virtual void func() = 0;

	//只要有一个纯虚函数,这个类就成为抽象类
	//纯虚函数的特点:
	//1、无法实例化对象
	//2、抽象类的子类 必须要重写父类中的纯虚函数 否则也属于抽象类

public:

};

class son :public base
{
public:
	void func()
	{
		cout << "子类函数的调用" << endl;
	}
};

void test02()
{
	son s;//子类必须要重写父类中的俄纯虚函数,否则不能实例化对象

	//多态函数调用的条件 父类指针需要指向子类
	base* b = new son;
	b->func();
	delete b;
}

int main()
{

	//test01();
	test02();

	system("pause");
	return 0;
}

虚析构函数

根据c++的只是可以知道,析构函数一般用于,该对象所在的函数运行完最后一行代码之后,对类中内存进行释放。

一般来说析构函数在写类的时候,不需要我们写,编译器(visual studio)内部会自动生成并调用。

  • 在多态语法中,使用虚析构函数和纯虚析构函数的一般条件是:

子类中存在堆区数据

在一般情况下,在使用多态语法之后,如果不使用虚析构语法,若子类中含有堆区上的数据,函数运行完成之后,只会运行父类的析构函数,而不会运行子类的析构函数(尽管子类中实现了析构函数),从而会造成内存泄漏的状况

#include<iostream>
using namespace std;

class animal
{
public:
	animal()
	{
		cout << "animal的构造函数的调用" << endl;
	}
	virtual void speak() = 0;
	
    //这里在父类中实现了析构函数
	~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()
	{
		if (m_name != NULL)
		{
			cout << "cat析构函数的调用" << endl;
			delete m_name;
			m_name = NULL;
		}
	}
public:

	string *m_name;
};

void dospeak(animal * an)
{
	//父类指针再调用析构函数的时候,不会调用子类种的是析构函数,导致子类如果有堆区属性,会出现内存泄露的情况
	an->speak();
	delete an;
}

void test01()
{
	dospeak(new cat("tom"));
}

int main()
{

	test01();

	system("pause");
	return 0;
}
animal的构造函数的调用
cat构造函数的调用
tom小猫说话
animal的析构 函数的调用

可以看出并没有调用子类的析构函数。

如果想要避免内存泄露的情况,就需要在父类的析构函数前加上virtual关键字

class animal
{
public:
	animal()
	{
		cout << "animal的构造函数的调用" << endl;
	}
	virtual void speak() = 0;
	
	virtual ~animal()
	{
		cout << "animal的析构 函数的调用" << endl;
	}
};

输出结果:

animal的构造函数的调用
cat构造函数的调用
tom小猫说话
cat析构函数的调用
animal的析构 函数的调用

可以看出调用了子类cat的析构函数

纯虚析构函数

纯虚析构函数就是在虚析构函数的基础上,用纯虚函数的写法去写虚析构函数

class animal
{
public:
	animal()
	{
		cout << "animal的构造函数的调用" << endl;
	}
	virtual void speak() = 0;

	//如果是纯虚析构函数的俄写法,则需要在类内声明之后,还需要在类外实现
	//有了纯虚析构之后,这个类也属于抽象类,不可实例化
	virtual ~animal() = 0;
	
};

#纯虚析构函数需要在类外进行实现
animal::~animal()
{
	cout << "纯虚析构函数的的实现" << endl;
}

输出结果:

animal的构造函数的调用
cat构造函数的调用
tom小猫说话
cat析构函数的调用
animal的析构 函数的调用

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多态语法c++(自学笔记一) 的相关文章

随机推荐

  • QTREE5 - Query on a tree V【LCT】

    题目链接 你被给定一棵n个点的树 点从1到n编号 每个点可能有两种颜色 黑或白 我们定义dist a b 为点a至点b路径上的边个数 一开始所有的点都是黑色的 要求作以下操作 0 i 将点i的颜色反转 黑变白 白变黑 1 v 询问dist
  • Snipaste 使用方法

    下载 Snipaste 下载完成后 解压文件如图 双击Snipaste exe后 可以看到状态栏中有 右键图标可以看到详细配置信息 按需配置即可 截图之后点击下图红框图钉可以钉住截图区域
  • python 笔记:PyTrack(将GPS数据和OpenStreetMap数据进行整合)【官网例子解读】

    论文笔记 PyTrack A Map Matching Based Python Toolbox for Vehicle Trajectory Reconstruction UQI LIUWJ的博客 CSDN博客4 0 包的安装 官网的两种
  • JavaWeb实现查询功能

    写在前面 你们好 我是小庄 很高兴能和你们一起学习JavaWeb 如果您对Java感兴趣的话可关注我的动态 写博文是一种习惯 在这过程中能够梳理知识和巩固知识点 需求 当搜索框为空时 查询数据库所有商品 输入商品名时 进行模糊查询 实现思路
  • SpringBoot JPA 中无法注入 JpaRepository 接口的问题及解决方案

    错误 No qualifying bean of type xxx xxx xxx available expected at least 1 bean which qualifies as autowire candidate Depen
  • C语言输出100以内的全部素数。

    include
  • matlab练习程序(灰度、二值图像腐蚀膨胀)

    cl img gray imread fupeng jpg img erzhi imread erzhi fupeng jpg imshow img gray figure imshow img erzhi m n size img gra
  • 文件目录大小

    题目描述 一个文件目录的数据格式为 目录id 本目录中文件大小 子目录id列表 其中目录id全局唯一 取值范围 1 200 本目录中文件大小范围 1 1000 子目录id列表个数 0 10 例如 1 20 2 3 表示目录1中文件总大小是2
  • 解决 vba 报错:要在64位系统上使用,请检查并更新Declare 语句

    将错误处的 Declare 替换成 Declare PtrSafe 即可
  • java正则

    一 Pattern类和Matcher类 java util regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包 它包括两个类 Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表
  • docker 安装向量数据库 Milvus

    Miluvs 官网为 www milvus io Milvus 向量数据库能够帮助用户轻松应对海量非结构化数据 图片 视频 语音 文本 检索 单节点 Milvus 可以在秒内完成十亿级的向量搜索 请参考 在线教程 分布式架构亦能满足用户的水
  • LSTM模型预测新冠

    LSTM是RNN的改进型 传统RNN模型会随着时间区间的增长 对早期的因素的权重越来越低 有可能会损失重要数据 而LSTM模型通过遗忘门 输入门 输出门三个逻辑 来筛选和保留数据 原理详解可以参考如何从RNN起步 一步一步通俗理解LSTM这
  • (二叉)树的遍历

    树 包括图 在遍历时都存在两种方式 深度优先遍历和广度优先遍历 树 一定有一个根节点 而图 没有根节点 但图中的任意节点都可以作为根节点使用 当然该节点一定要有边 否则没有意义 深度优先遍历 访问当前节点 将当前节点的children作为子
  • spacemacs删除行尾无意义的空格符号

    SPC SPC delete trailing whitespace 或者 SPC x d w
  • 2019年全球安全态度调查:越来越多的受害者向勒索软件支付赎金

    根据网络安全公司CrowdStrike 发布的 2019年全球安全态度调查 的数据 在供应链攻击后 危害黑客以支付赎金的组织总数从14 增长到39 与去年同期相比翻了一番 其中最典型的是英国 2019年 遭受勒索软件攻击并支付勒索赎金的组织
  • fastadmin public js 内 selectpage 联动下拉

    js 页面 define jquery bootstrap backend table form selectpage function undefined Backend Table Form var Controller index f
  • 如何使用Git工具克隆GitHub仓库到本地

    首先 确保你已经在本地安装了Git 如果没有安装 可以前往Git官方网站 https git scm com 下载并安装适合你操作系统的版本 在本地文件夹打开Git Bash 如果你使用Windows系统 在GitHub上找到你想要克隆的仓
  • UE Cook遇到的一些问题

    UE Cook是什么 简单来说 把UE资源 比如uasset umap等转换成平台能识别的资源类型 Cook中遇到的报错 找不到文件 说明你有些plugin没有加入到当前 Project uproject中去 UATHelper Cooki
  • 35岁,一个团队leader,从工作满8年的公司离职,选择重新尝试新机会,或许35岁才是起点。

    目录 面试 1 年龄大找工作一定要有目标 不能太随便 2 代码能力是整个IT行业的核心技能 也是对整个行业从业者的要求 3 沟通表达很重要 把自己做过的事情做到极致 然后能讲出来 4 心态要好 5 机会总是留给有准备的人 勿浮躁 先沉淀 厚
  • 多态语法c++(自学笔记一)

    多态中的纯虚函数 使用多态时 当子类继承父类之后 一般来说对于父类只是作为提供相应的成员变量和成员函数的一个集合 在实际项目中 如果想要修改某一部分的功能 按照以往普通的类的写法 就需要修改类中的代码 也可以说是源码 这样会显得很不方便和不