【C++】多态、黑马程序员案例— —电脑组装、Visual Studio开发人员工具查看内部结构,cl /d1 reportSingleClassLayout

news2024/9/27 23:28:29

author:&Carlton

tag:C++

topic:【C++】多态、黑马程序员案例— —电脑组装、Visual Studio开发人员工具查看内部结构,cl /d1 reportSingleClassLayout

website:黑马程序员C++

date:2023年7月24日


目录

纯虚函数、抽象类

案例— —电脑组装

抽象类(父类):CPU、显卡、内存条

零件厂商类(子类):Intel、Amd

电脑类:零件搭配,零件工作调用

三个测试对象(电脑对象)

源代码

运行结果

虚函数作用效果与内部结构变化

运行结果变化 

内部结构变化


纯虚函数、抽象类

        类中只要有一个纯虚函数那这个类就是抽象类,不能实例化对象,而且它的子类必须重写纯虚函数,否则也为抽象类。

案例— —电脑组装

抽象类(父类):CPU、显卡、内存条

//抽象CPU类
class AbstractCPU
{
public:
	virtual void calculate() = 0;		//纯虚函数
};

//抽象显卡类
class AbstractVideoCard
{
public:
	virtual void display() = 0;	
};

//抽象内存条类
class AbstractMemory
{
public:
	virtual void storage() = 0;		
};

零件厂商类(子类):Intel、Amd

//Intel厂商CPU类
class IntelCPU:public AbstractCPU
{
public:
	void calculate()		//函数重写
	{
		cout << "Intel的CPU在工作" << endl;
	}
};

//Intel厂商显卡类
class IntelVideoCard :public AbstractVideoCard
{
public:
	void display()	
	{
		cout << "Intel的显卡在工作" << endl;
	}
};

//Intel厂商内存条类
class IntelMemory :public AbstractMemory
{
public:
	void storage()
	{
		cout << "Intel的内存条在工作" << endl;
	}
};

//Amd厂商CPU类
class AmdCPU :public AbstractCPU
{
public:
	void calculate()
	{
		cout << "Amd的CPU在工作" << endl;
	}
};

//Amd厂商显卡类
class AmdVideoCard :public AbstractVideoCard
{
public:
	void display()
	{
		cout << "Amd的显卡在工作" << endl;
	}
};

//Amd厂商内存条类
class AmdMemory :public AbstractMemory
{
public:
	void storage()
	{
		cout << "Amd的内存条在工作" << endl;
	}
};

电脑类:零件搭配,零件工作调用

//电脑类
class Computer
{
public:

	//使用父类指针定义子类对象
	AbstractCPU* m_cpu;
	AbstractVideoCard* m_videocard;
	AbstractMemory* m_memory;
	
	//初始化搭配零件
	Computer(AbstractCPU* cpu,AbstractVideoCard* videocard,AbstractMemory* memory)
	{
		m_cpu = cpu;
		m_videocard = videocard;
		m_memory = memory;
	}
	
	//电脑工作函数
	//调用三个零件
	void work()
	{
		m_cpu->calculate();
		m_videocard->display();
		m_memory->storage();
	}
};

三个测试对象(电脑对象)

//组装第一台电脑
void test01()
{
	cout << "第一台电脑在工作:" << endl;

	//建立子类指针指向堆区内存区
	IntelCPU* cpu = new (IntelCPU);
	IntelVideoCard* videocard = new (IntelVideoCard);
	IntelMemory* memory = new (IntelMemory);

	Computer c1(cpu, videocard, memory);
	c1.work();

	delete cpu;
	delete videocard;
	delete memory;
}

//组装第二台电脑
void test02()
{
	cout << "第二台电脑在工作:" << endl;

	AmdCPU* cpu = new (AmdCPU);
	AmdVideoCard* videocard = new (AmdVideoCard);
	AmdMemory* memory = new (AmdMemory);

	Computer c1(cpu, videocard, memory);
	c1.work();

	delete cpu;
	delete videocard;
	delete memory;
}

//组装第三台电脑
void test03()
{
	cout << "第三台电脑在工作:" << endl;

	IntelCPU* cpu = new (IntelCPU);
	AmdVideoCard* videocard = new (AmdVideoCard);
	IntelMemory* memory = new (IntelMemory);

	Computer c1(cpu, videocard, memory);
	c1.work();

	delete cpu;
	delete videocard;
	delete memory;
}

源代码

#include <iostream>
using namespace std;

//抽象CPU类
class AbstractCPU
{
public:
	virtual void calculate() = 0;		//纯虚函数
};

//抽象显卡类
class AbstractVideoCard
{
public:
	virtual void display() = 0;	
};

//抽象内存条类
class AbstractMemory
{
public:
	virtual void storage() = 0;		
};

//Intel厂商CPU类
class IntelCPU:public AbstractCPU
{
public:
	void calculate()		//函数重写
	{
		cout << "Intel的CPU在工作" << endl;
	}
};

//Intel厂商显卡类
class IntelVideoCard :public AbstractVideoCard
{
public:
	void display()	
	{
		cout << "Intel的显卡在工作" << endl;
	}
};

//Intel厂商内存条类
class IntelMemory :public AbstractMemory
{
public:
	void storage()
	{
		cout << "Intel的内存条在工作" << endl;
	}
};

//Amd厂商CPU类
class AmdCPU :public AbstractCPU
{
public:
	void calculate()
	{
		cout << "Amd的CPU在工作" << endl;
	}
};

//Amd厂商显卡类
class AmdVideoCard :public AbstractVideoCard
{
public:
	void display()
	{
		cout << "Amd的显卡在工作" << endl;
	}
};

//Amd厂商内存条类
class AmdMemory :public AbstractMemory
{
public:
	void storage()
	{
		cout << "Amd的内存条在工作" << endl;
	}
};

//电脑类
class Computer
{
public:

	//使用父类指针定义子类对象
	AbstractCPU* m_cpu;
	AbstractVideoCard* m_videocard;
	AbstractMemory* m_memory;
	
	//初始化搭配零件
	Computer(AbstractCPU* cpu,AbstractVideoCard* videocard,AbstractMemory* memory)
	{
		m_cpu = cpu;
		m_videocard = videocard;
		m_memory = memory;
	}
	
	//电脑工作函数
	//调用三个零件
	void work()
	{
		m_cpu->calculate();
		m_videocard->display();
		m_memory->storage();
	}
};

//组装第一台电脑
void test01()
{
	cout << "第一台电脑在工作:" << endl;

	//建立子类指针指向堆区内存区
	IntelCPU* cpu = new (IntelCPU);
	IntelVideoCard* videocard = new (IntelVideoCard);
	IntelMemory* memory = new (IntelMemory);

	Computer c1(cpu, videocard, memory);
	c1.work();

	delete cpu;
	delete videocard;
	delete memory;
}

//组装第二台电脑
void test02()
{
	cout << "第二台电脑在工作:" << endl;

	AmdCPU* cpu = new (AmdCPU);
	AmdVideoCard* videocard = new (AmdVideoCard);
	AmdMemory* memory = new (AmdMemory);

	Computer c1(cpu, videocard, memory);
	c1.work();

	delete cpu;
	delete videocard;
	delete memory;
}

//组装第三台电脑
void test03()
{
	cout << "第三台电脑在工作:" << endl;

	IntelCPU* cpu = new (IntelCPU);
	AmdVideoCard* videocard = new (AmdVideoCard);
	IntelMemory* memory = new (IntelMemory);

	Computer c1(cpu, videocard, memory);
	c1.work();

	delete cpu;
	delete videocard;
	delete memory;
}

int main()
{
	test01();
	cout << "---------------" << endl;
	test02();
	cout << "---------------" << endl;
	test03();
	return 0;
}

运行结果

 

虚函数作用效果与内部结构变化

更改抽象CPU类的calculate函数,不使用虚函数

运行结果变化 

        ”CPU不再工作“,不再打印CPU在工作的这一句话,说明此时即便父类指针指向子类对象,但由于没有在父类(即这里的抽象类)上用virtual关键字修饰使用虚函数,没有完成运行多态,对象调用的是父类的calculate函数(即一个空函数)

 

内部结构变化

使用virtual修饰: 

不适用虚函数后:

 

欢迎指正与分享,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/809034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

map的初始化、erase()、写入与写出

运行代码&#xff1a; //map的初始化、erase()、写入与写出 #include"std_lib_facilities.h"istream& operator>>(istream& is, map<string, int>&mm) {string ss"";int ii0;is >> ss;if(is>>ii)mm[ss] ii;return i…

【数据集】3小时尺度降水数据集-MSWEPV2

1 MSWEP V2 precipitation product 官网-MSWEP V2降水产品 参考

《向量数据库指南》:向量数据库Pinecone如何集成LangChain (一)

目录 LangChain中的检索增强 建立知识库 欢迎使用Pinecone和LangChain的集成指南。本文档涵盖了将高性能向量数据库Pinecone与基于大型语言模型(LLMs)构建应用程序的框架LangChain集成的步骤。 Pinecone使开发人员能够基于向量相似性搜索构建可扩展的实时推荐和搜索系统…

redis之Bitmap

位图数据结构其实并不是一个全新的玩意&#xff0c;我们可以简单的认为就是个数组&#xff0c;只是里面的内容只能为0或1而已(二进制位数组)。 GETBIT用于返回位数组在偏移量上的二进制位的值。值得我们注意的是&#xff0c;GETBIT的时间复杂度是O(1)。 GETBIT命令的执行过程如…

LeetCode 75 第十三题(1679)K和数对的最大数目

题目: 示例: 分析: 给一个数组&#xff0c;两个和为K的数为一组&#xff0c;问能凑成几组。 既然一组是两个数&#xff0c;那么我们可以使用双指针分别指向数组首尾&#xff0c;然后再判断能否凑成和为K的组. 在使用双指针寻找之前,我们应当先将数组排序(升序降序都无所谓),…

[SSM]Spring面向切面编程AOP

目录 十五、面向切面编程AOP 15.1AOP介绍 15.2AOP的七大术语 15.3切点表达式 15.4使用Spring的AOP 15.4.1准备工作 15.4.2基于AspectJ的AOP注解式开发 15.4.3基于XML配置方式的AOP&#xff08;了解&#xff09; 15.5AOP的实际案例&#xff1a;事务处理 15.6AOP的实际…

flask用DBUtils实现数据库连接池

flask用DBUtils实现数据库连接池 在 Flask 中&#xff0c;DBUtils 是一种实现数据库连接池的方案。DBUtils 提供了持久性&#xff08;persistent&#xff09;和透明的&#xff08;transient&#xff09;两种连接池类型。 首先你需要安装 DBUtils 和你需要的数据库驱动。例如&…

关于c++中虚函数和虚函数表的创建时机问题

以这段代码为例。 #include <iostream>using namespace std;class Parent { public:Parent(){}virtual void func1() {};virtual void func2() {}; };class Child :public Parent { public:Child():n(0),Parent(){cout << "Child()" << endl;}vir…

【机器学习】西瓜书学习心得及课后习题参考答案—第4章决策树

这一章学起来较为简单&#xff0c;也比较好理解。 4.1基本流程——介绍了决策树的一个基本的流程。叶结点对应于决策结果&#xff0c;其他每个结点则对应于一个属性测试&#xff1b;每个结点包含的样本集合根据属性测试的结果被划分到子结点中&#xff1b;根结点包含样本全集&a…

js中的遍历方法比较:map、for...in、for...of、reduce和forEach的特点与适用场景

&#x1f60a;博主&#xff1a;小猫娃来啦 &#x1f60a;文章核心&#xff1a;JavaScript中的遍历方法比较&#xff1a;map、for…in、for…of和forEach的特点与适用场景 文章目录 map 方法概述用法返回值特点 for...in 循环概述用法注意事项 for...of 循环概述用法可迭代对象…

苍穹外卖day09——历史订单模块(用户端)+订单管理模块(管理端)

查询历史订单——需求分析与设计 产品原型 业务规则 分页查询历史订单 可以根据订单状态查询 展示订单数据时&#xff0c;需要展示的数据包括&#xff1a;下单时间、订单状态、订单金额、订单明细&#xff08;商品名称、图片&#xff09; 接口设计 查询历史订单——代码开…

抖音seo短视频账号矩阵系统技术开发简述

说明&#xff1a;本开发文档适用于抖音seo源码开发&#xff0c;抖音矩阵系统开发&#xff0c;短视频seo源码开发&#xff0c;短视频矩阵系统源码开发 一、 抖音seo短视频矩阵系统开发包括 抖音seo短视频账号矩阵系统的技术开发主要包括以下几个方面&#xff1a; 1.前端界面设…

线程初见——对速度的追求

文章目录 线程进程线程区别线程之间资源线程库介绍 线程 同一个程序的所有线程共享一份全局内存区域 特例&#xff1a;只包含一个线程的进程 查看线程号&#xff1a;ps -Lf 号 和进程类似&#xff0c;完成并发任务的执行 进程线程区别 区别进程线程信息交换内存未共享&#xf…

cad丢失mfc140u.dll怎么办?找不到mfc140u.dll的解决方法

第一&#xff1a;mfc140u.dll有什么用途&#xff1f; mfc140u.dll是Windows操作系统中的一个动态链接库文件&#xff0c;它是Microsoft Foundation Class (MFC)库的一部分。MFC是 C中的一个框架&#xff0c;用于构建Windows应用程序的用户界面和功能。mfc140u.dll包含了MFC库中…

CAN15765和1939协议

1. 15765协议介绍 简单的来说&#xff0c;15765协议指的是 基于CAN2.0A/B 协议 &#xff08;也可以叫做ISO11898协议 -链路层&#xff09; 硬件接口的 应用层 通讯协议&#xff0c; 它用于实现通用的车辆诊断服务。 ISO11898协议参考下图。 参考搜索到的“CAN总线协议讲解…

【MySQL】索引特性

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《零基础入门MySQL》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;没…

蓝图节点编辑器

打印字符串 第02章 蓝图结构 03 -注释和重新路由_哔哩哔哩_bilibili 第02章 蓝图结构 04 - 变量_哔哩哔哩_bilibili 第03章 蓝图简易门 01 - 箱子碰撞_哔哩哔哩_bilibili 第03章 蓝图简易门 02 - 静态Mesh和箭头_哔哩哔哩_bilibili 第03章 蓝图简易门 03 - 设置相对旋转节点_哔…

流数据湖平台Apache Paimon(三)Flink进阶使用

文章目录 2.9 进阶使用2.9.1 写入性能2.9.2 读取性能2.9.3 多Writer并发写入2.9.4 表管理2.9.5 缩放Bucket 2.10 文件操作理解2.10.1 插入数据2.10.2 删除数据2.10.3 Compaction2.10.4 修改表2.10.5 过期快照2.10.6 Flink 流式写入 2.9 进阶使用 2.9.1 写入性能 Paimon的写入…

c++ 类的特殊成员函数:拷贝构造函数(四)

1. 简介 拷贝构造是一种特殊的构造函数&#xff0c;用于创建一个对象&#xff0c;该对象是从同一类中的另一个对象复制而来的。拷贝构造函数通常采用引用参数来接收要复制的对象&#xff0c;并使用该对象的副本来创建一个新对象。 2. 结构 class MyClass { public:MyClass(c…

一种新的基于区域的在线活动轮廓模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…