C++电脑组装项目(涉及知识点:多态,虚析构,使用父类指针和new关键字实例化子类时无法调用子类的析构函数,类的头文件和类的cpp文件的使用,父类中调用子类的析构函数)

一.电脑组装项目各文件的关系和cpp文件目录

在这里插入图片描述
在这里插入图片描述

二.使用父类指针和new关键字实例化子类时无法调用子类的析构函数

即使用如下代码,不会调用IntelCpu的析构函数。导致无法释放子类申请的空间。

AbstractCpu* cpu = new IntelCpu;
delete cpu;

完整代码如下:

AbstractCpu.h

#pragma once
#include<iostream>
using namespace std;


class AbstractCpu
{
public:
    virtual void calculate() = 0;

    ~AbstractCpu()
    {
        cout<<"我调用了AbstractCpu的析构函数"<<endl;
    }
};

IntelCpu.h

#pragma once
#include "AbstractCpu.h"
#include "iostream"

using namespace std;

class IntelCpu: public AbstractCpu
{
public:
    IntelCpu()
    {
        cout<<"我调用了IntelCPU的构造函数"<<endl;
    }

    ~IntelCpu();
    {
        cout<<"我调用了IntelCPU的西狗函数"<<endl;
    }
    void calculate();
};

IntelCpu.cpp

#include "IntelCpu.h"

void IntelCpu::calculate()
{
    cout<<"Intel的CPU开始计算了"<<endl;
}

main.cpp

#include <iostream>
#include "Computer.h"
#include "AbstractCpu.h"
#include "IntelCpu.h"


using namespace std;

int main()
{   
    AbstractCpu* cpu = new IntelCpu;

    delete cpu;

    return 0;
}
g++ main.cpp src/IntelCpu.cpp src/IntelMemory.cpp src/IntelVideoCard.cpp src/Computer.cpp -Iinclude

在这里插入图片描述

发现根本没调用IntelCpu的析构函数。
因为我们用父类的指针指向子类IntelCpu,当delete cpu;时,父类调用自己的析构函数并不会执行子类的析构函数。

三.在父类中使用虚析构,解决上面的问题

AbstractCpu.cpp

#pragma once
#include<iostream>
using namespace std;


class AbstractCpu
{
public:
    AbstractCpu()
    {
        cout<<"我调用了AbstractCpu的构造函数"<<endl;
    }
    
    virtual void calculate() = 0;

    virtual ~AbstractCpu()
    {
        cout<<"我调用了AbstractCpu的析构函数"<<endl;
    }
};

IntelCpu.cpp

#pragma once
#include "AbstractCpu.h"
#include "iostream"

using namespace std;

class IntelCpu: public AbstractCpu
{
public:
    IntelCpu()
    {
        cout<<"我调用了IntelCPU的构造函数"<<endl;
    }

    ~IntelCpu();
    {
        cout<<"我调用了IntelCPU的西狗函数"<<endl;
    }
    void calculate();
};

main.cpp

#include <iostream>
#include "Computer.h"
#include "AbstractCpu.h"
#include "IntelCpu.h"


using namespace std;

int main()
{   
    AbstractCpu* cpu = new IntelCpu;

    delete cpu;

    return 0;
}
g++ main.cpp src/IntelCpu.cpp src/IntelMemory.cpp src/IntelVideoCard.cpp src/Computer.cpp -Iinclude

在这里插入图片描述

四.电脑组装项目:方法一: Computer类中调用子类的析构函数

include文件下

AbstractCpu.h

#pragma once
#include<iostream>
using namespace std;


class AbstractCpu
{
public:
    AbstractCpu()
    {
        cout<<"我调用了AbstractCpu的构造函数"<<endl;
    }
    
    virtual void calculate() = 0;

    virtual ~AbstractCpu()
    {
        cout<<"我调用了AbstractCpu的析构函数"<<endl;
    }
};

AbstractMemory.h

#pragma once
#include<iostream>
using namespace std;

class AbstractMemory
{
public:
    AbstractMemory()
    {
        cout<<"我调用了AbstractMemory的构造函数"<<endl;
    }
    virtual void storage() = 0;

    virtual ~AbstractMemory()
    {
        cout<<"我调用了AbstractMemory的析构函数"<<endl;
    }
};

AbstractVideoCard.h

#pragma once
#include<iostream>
using namespace std;

class AbstractVideoCard
{
public:
    AbstractVideoCard()
    {
        cout<<"我调用了AbstractVideoCard的构造函数"<<endl;
    }
    virtual void display() = 0;

    virtual ~AbstractVideoCard()
    {
        cout<<"我调用了AbstractVideoCard的构造函数"<<endl;
    }
};

Computer.h

#pragma once
#include <iostream>
#include "AbstractCpu.h"
#include "AbstractMemory.h"
#include "AbstractVideoCard.h"
using namespace std;

class Computer
{
private:
    AbstractCpu* m_cpu;
    AbstractVideoCard* m_vc;
    AbstractMemory* m_mem;

public:
    Computer(AbstractCpu* cpu,AbstractVideoCard* video_card,AbstractMemory* memory)
    {
        cout<<"我调用了Computer的构造函数"<<endl;
        this->m_cpu = cpu;
        this->m_vc = video_card;
        this->m_mem = memory;
    }

    void run();

    //如果不在头文件中写函数的实现,在cpp文件中写文件的实现则必须声明。
    ~Computer();
};

IntelCpu.h

#pragma once
#include "AbstractCpu.h"
#include<iostream>

using namespace std;

class IntelCpu: public AbstractCpu
{
public:
    IntelCpu()
    {
        cout<<"我调用了IntelCPU的构造函数"<<endl;
    }

    ~IntelCpu()
    {
        cout<<"我调用了IntelCPU的西狗函数"<<endl;
    }
    void calculate();
};

IntelMemory.h

#pragma once
#include "AbstractMemory.h"
#include<iostream>

using namespace std;

class IntelMemory: public AbstractMemory
{
public:
    IntelMemory()
    {
        cout<<"我调用了IntelMemory的构造函数"<<endl;
    }

    ~IntelMemory()
    {
        cout<<"我调用了IntelMemory的西狗函数"<<endl;
    }
    void storage();
};

IntelVideoCard.h

#pragma once
#include "AbstractVideoCard.h"
#include "iostream"

using namespace std;

class IntelVideoCard: public AbstractVideoCard
{
public:

    IntelVideoCard()
    {
        cout<<"我调用了IntelVideoCard的构造函数"<<endl;
    }

    ~IntelVideoCard()
    {
        cout<<"我调用了IntelVideoCard的西狗函数"<<endl;
    }

    void display();
};

src

Computer.cpp

#include "Computer.h"

void Computer::run()
{
    m_cpu->calculate();
    m_vc->display();
    m_mem->storage();
}

Computer::~Computer()
{
    cout<<"我调用了Computer的西狗函数"<<endl;

    if(m_cpu!=NULL)
    {
        cout<<"delete m_cpu"<<endl;
        delete m_cpu;
        m_cpu = NULL;
    }

    if(m_vc!=NULL)
    {
        cout<<"delete m_vc"<<endl;
        delete m_vc;
        m_vc = NULL;
    }
    
    if(m_mem!=NULL)
    {
        cout<<"delete m_mem"<<endl;
        delete m_mem;
        m_mem = NULL;
    }
} 

IntelCpu.cpp

#include "IntelCpu.h"

void IntelCpu::calculate()
{
    cout<<"Intel的CPU开始计算了"<<endl;
}

IntelMemory.cpp

#include "IntelMemory.h"

void IntelMemory::storage()
{
    cout<<"Intel的memory开始计算了"<<endl;
}

IntelVideoCard.cpp

#include "IntelVideoCard.h"

void IntelVideoCard::display()
{
    cout<<"Intel的VideoCard开始计算了"<<endl;
}

main.cpp

#include <iostream>
#include "Computer.h"
#include "AbstractCpu.h"
#include "AbstractMemory.h"
#include "AbstractVideoCard.h"
#include "IntelCpu.h"
#include "IntelMemory.h"
#include "IntelVideoCard.h"

using namespace std;

int main()
{   
    AbstractCpu* cpu = new IntelCpu;
    AbstractMemory* memory = new IntelMemory;
    AbstractVideoCard* videocard = new IntelVideoCard;

     //为什么这样报错?
    // Computer c = Computer(cpu,memory,videocard);
   
    Computer* computer = new Computer(cpu,videocard,memory);

    computer->run();

    delete computer;
    return 0;
}

在这里插入图片描述

五.电脑组装项目:方法二: main文件中delete创建的子类

只需要修改main.cpp, Computer的头文件对析构函数的声明和Computer.cpp

mian.cpp

#include <iostream>
#include "Computer.h"
#include "AbstractCpu.h"
#include "AbstractMemory.h"
#include "AbstractVideoCard.h"
#include "IntelCpu.h"
#include "IntelMemory.h"
#include "IntelVideoCard.h"

using namespace std;

int main()
{   
    AbstractCpu* cpu = new IntelCpu;
    AbstractMemory* memory = new IntelMemory;
    AbstractVideoCard* videocard = new IntelVideoCard;
   
    Computer* computer = new Computer(cpu,videocard,memory);

    computer->run();

    delete cpu;
    delete memory;
    delete videocard;
    delete computer;

    return 0;
}

Computer.h

#pragma once
#include <iostream>
#include "AbstractCpu.h"
#include "AbstractMemory.h"
#include "AbstractVideoCard.h"
using namespace std;

class Computer
{
private:
    AbstractCpu* m_cpu;
    AbstractVideoCard* m_vc;
    AbstractMemory* m_mem;

public:
    Computer(AbstractCpu* cpu,AbstractVideoCard* video_card,AbstractMemory* memory)
    {
        cout<<"我调用了Computer的构造函数"<<endl;
        this->m_cpu = cpu;
        this->m_vc = video_card;
        this->m_mem = memory;
    }

    void run();

    //如果不在头文件中写函数的实现,在cpp文件中写文件的实现则必须声明。
    // ~Computer();
};

Computer.cpp

#include "Computer.h"

void Computer::run()
{
    m_cpu->calculate();
    m_vc->display();
    m_mem->storage();
}

// Computer::~Computer()
// {
//     cout<<"我调用了Computer的西狗函数"<<endl;

//     if(m_cpu!=NULL)
//     {
//         cout<<"delete m_cpu"<<endl;
//         delete m_cpu;
//         m_cpu = NULL;
//     }

//     if(m_vc!=NULL)
//     {
//         cout<<"delete m_vc"<<endl;
//         delete m_vc;
//         m_vc = NULL;
//     }
    
//     if(m_mem!=NULL)
//     {
//         cout<<"delete m_mem"<<endl;
//         delete m_mem;
//         m_mem = NULL;
//     }
// } 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华清远见嵌入式学习——网络编程——作业3

目录 作业要求&#xff1a;基于UDP的TFTP文件传输 代码 下载功能效果图​编辑 上传功能效果图 思维导图 模拟面试题和答案&#xff08;定期更新&#xff09; 作业要求&#xff1a;基于UDP的TFTP文件传输 完成文件的上传和下载功能 代码 #include<myhead.h>//实现…

一站式解决Mac音视频转换需求——Xilisoft Video Converter Ultimate for Mac

在数字化时代&#xff0c;音视频的应用越来越广泛&#xff0c;不同的设备和平台对音视频格式的要求也不尽相同。因此&#xff0c;如何找到一款功能强大、易于操作的音视频转换软件成为了Mac用户的迫切需求。而Xilisoft Video Converter Ultimate for Mac&#xff08;曦力音视频…

亚马逊智能机器人Astro新升级!可为中小企业提供巡逻服务

原创 | 文 BFT机器人 Astro是Amzon近年来推出的一种新型的家用机器人&#xff0c;由智能助手Alexa驱动&#xff0c;主要用于家庭监控&#xff0c;如检查炉子、水龙头是否开着&#xff0c;以及其他任务。它将人工智能、计算机视觉、传感器技术以及语音和边缘计算方面的新进展汇…

linux -系统通用命令查询

有时候内网环境下&#xff0c;系统有些命令没有安装因此掌握一些通用的linux 命令也可以帮助我们解决一些问题查看 1.查看系统内核版本 uname -r2.查看系统版本 cat /etc/os-release3. 查看cpu 配置 lscpu4.查看内存信息 free [参数] 中各个数值的解释如下表 数值解释t…

宿主Linux——KVM安装Windows7系统

KVM虚拟技术 KVM(Kernel-based Virtual Machine) 是基于Linux内核的开源虚拟化技术&#xff0c;在一台物理机上可同时运行多个虚拟系统。KVM使用硬件虚拟化扩展&#xff0c;例如Intel的VT和AMD的AMD-V&#xff0c;在性能方面更加高效&#xff0c;可提供更好的计算能力和响应速…

启发式搜索算法-人工智能

第1关:评估函数和启发信息 第2关:A*搜索算法 class Array2D:"""说明:1.构造方法需要两个参数,即二维数组的 宽和高2.成员变量w和h是二维数组的宽和高3.使用:‘对象[x][y]’可以直接取到相应的值4.数组的默认值都是0"""def __init__(s…

Python语言创建爬虫代理ip池详细步骤和代码示例

作为长期游弋于代码世界中的程序猿来说&#xff0c;拥有自己的服务器以及代理池能够让自己网络爬虫更得心应手。那么新手如何创建自己的私有IP池呢&#xff1f;它的步骤又有哪些&#xff1f;带着这些问题我们意义探讨。 以我多年的爬虫经验创建一个IP池的大体上可以分为以下几个…

可上手 JVM 调优实战指南

文章目录 为什么要学 JVM一、JVM 整体布局二、Class 文件规范三、类加载模块四、执行引擎五、GC 垃圾回收1 、JVM内存布局2 、 JVM 有哪些主要的垃圾回收器&#xff1f;3 、分代垃圾回收工作机制 六、对 JVM 进行调优的基础思路七、 GC 情况分析实例八、最后总结 全程可上手JVM…

又下一城!文心中国行入厦,大模型助推区域产业智能化提速

11月22日&#xff0c;“文心中国行”落地厦门。活动现场&#xff0c;厦门火炬高技术产业开发区管委会、厦门市思明区政府授予百度飞桨“人工智能公共技术服务平台”并举行授牌仪式。来自当地政产学研各界的领导、专家、企业嘉宾分享了AI大模型的最新技术趋势、产教融合开源共创…

React16中打印事件对象取不到值的现象及其原因分析

React16中打印事件对象取不到值的现象及其原因分析 一、背景 在最近的开发过程中&#xff0c;遇到了一个看起来匪夷所思的问题❓&#xff1a; <Inputplaceholder"请输入"onChange{(e) > {console.log(e:, e)}}onKeyDown{handleKeyDown} />此时按理来说我…

畅谈Linux在小型微型企业中的应用

在这篇文章里我们讨论和畅谈一下linux系统在小微型企业中的应用&#xff0c;为什么会写这篇文章呢&#xff1f;因为在平时的工作中&#xff0c;认识的一些做小微型企业的朋友&#xff0c;他们经常找我咨询或是去解决一些平时工作中的IT相关的问题&#xff0c;那么小微型企业中的…

人物血条的制作_unity基础开发教程

人物血条的制作 场景创建导入素材血条制作血量控制代码部分 场景创建 随便创建一个地板、一个胶囊体&#xff0c;搭建一个简易的场景&#xff0c;我这里就继续使用前面文章创建的场景 导入素材 在unity编辑器中选择Window&#xff0c;点击Asset Store 点击Search online 在搜…

Course1-Week1:机器学习简介

Course1-Week1&#xff1a;机器学习简介 文章目录 Course1-Week1&#xff1a;机器学习简介1. 课程简介1.1 课程大纲1.2 Optional Lab的使用 (Jupyter Notebooks)1.3 欢迎参加《机器学习》课程 2. 机器学习简介2.1 机器学习定义2.2 有监督学习2.3 无监督学习 3. 线性回归模型3.1…

垂直领域生成式AI模型的矿业应用

快速发展的人工智能 (AI) 领域正在出现一种新范式&#xff1a;更小的、垂直的生成式 AI 模型。 这种方法不同于旨在解决许多问题的传统横向模型。 相反&#xff0c;它开发专门的人工智能模型来解决特定行业或垂直领域的问题。 垂直导向的生成式AI模型迎合特定行业&#xff0c;提…

【nlp】3.2 Transformer论文复现:1. 输入部分(文本嵌入层和位置编码器)

Transformer论文复现:输入部分(文本嵌入层和位置编码器) 1 输入复现1.1 文本嵌入层1.1.1 文本嵌入层的作用1.1.2 文本嵌入层的代码实现1.1.3 文本嵌入层中的注意事项1.2 位置编码器1.2.1 位置编码器的作用1.2.2 位置编码器的代码实现1.2.3 位置编码器中的注意事项1 输入复现…

上海 · 得物技术沙龙-「项目管理」专场报名开启!

随着业务的快速发展以及资源规模的增长&#xff0c;项目管理也需要根据团队规模及不同阶段的特点及时做好调整及应对。PMO/项目经理承担着资源使用、项目进度、团队协作等相关管理工作&#xff0c;过程的成功与否也决定着团队交付目标是否达成&#xff0c;结果是否符合预期。本…

应用带通滤波器进行划痕检测

案例要求&#xff1a; 图为HALCON中的例图“surface_scratch”&#xff0c;请提取出图中的划痕。 案例分析&#xff1a; 图中明亮程度不一&#xff0c;划痕颜色较淡&#xff0c;因此不能用灰度BLOB分析的方法提取出目标区域。因此&#xff0c;先构造一个带通滤波器&#xff0…

企业计算机服务器中了locked勒索病毒怎么办,勒索病毒解密恢复

计算机网络为企业的生产生活提供了极大帮助&#xff0c;让企业逐步走向数字化办公&#xff0c;但随之而来的网络安全威胁也不断增多&#xff0c;网络勒索病毒病毒攻击企业计算机的事件频发&#xff0c;并且攻击加密手段也在不断提升。近期&#xff0c;云天数据恢复中心再次接到…

抖音商城小程序源码系统 附带完整的搭建教程

大家好啊&#xff0c;今天小编来给大家分享一款抖音商城小程序源码系统。这可是当下最热门的的项目之一。。抖音作为国内最大的短视频平台之一&#xff0c;拥有庞大的用户群体和丰富的社交功能。为了满足用户在抖音上购物和交易的需求&#xff0c;抖音商城小程序应运而生。 以…