当前位置: 首页 > news >正文

析构函数、拷贝构造

1、析构函数

析构函数的定义方式

函数名和类名相同,在类名前加~,没有返回值类型,没有函数形参(不能重载)

当对象生命周期结束的时候,系统会自动调用析构函数

先调用析构函数,再释放对象的空间

析构函数实现

#include <iostream>using namespace std;
class Person
{
private:int mAge;
public://无参构造Person(){cout<<"无参构造:"<<endl;}//无参构造Person(int age){mAge = age;cout<<"有参构造:"<<mAge<<endl;}//没有 void 和返回值~Person(){cout<<"析构函数:"<<mAge<<endl;}
};void test(){Person(20);{Person(30);}Person(40);
}int main(int argc, char *argv[])
{Person p1(10);test();return 0;
}

构造函数和析构函数的执行次序(面试题)

说白了函数从上到下执行,先执行到的先进栈,先执行有参或者无参构造,后退栈的后执行,执行析构函数

一般情况下,空的析构函数就足够,但是如果一个类有指针成员,这个类必须写析构函数,释放指针成员所指向空间

因为一个对象结束,系统默认回收的是这个对象本身的空间,但是它不会回收这个对象中指针成员指向的空间,所以如果一个类有指针成员,这个类必须写析构函数,释放指针成员所指向空间


#include <iostream>
#include <string.h>
#include <stdlib.h>using namespace std;
class Person
{
private:char *mName;
public:Person(){mName = NULL;}Person(char *name){mName = new char [strlen(name)+1];   //申请堆区空间strcpy(mName,name);cout<<"有参构造:"<<mName<<endl;}//没有 void 和返回值~Person(){if(mName != NULL){delete [] mName;cout<<"释放 Person 类的指针成员所指行向的 堆区空间"<<endl;}}
};int main(int argc, char *argv[])
{Person ml("ml");return 0;
}

最后调用析构函数释放掉 Person 类的指针成员所指行向的 堆区空间

2、拷贝构造

实现拷贝构造

 //Person类中的深拷贝Person(const Person &ob){mName = new char [strlen(ob.mName)+1];   //申请堆区空间strcpy(mName,ob.mName);cout<<"有参构造:"<<ob.mName<<endl;}Person ml("ml");
Person m = ml;  //深拷贝

拷贝构造本质是构造函数

在上面的代码中,旧对象给新对象初始化就会调用拷贝构造函数,ob就是旧对象的引用

系统默认的拷贝是浅拷贝,能完成基本的赋值操作,一旦实现了拷贝构造函数必须实现赋值操作,因为系统默认的函数以及无效了

const Person &ob 代表的是当前类的常引用,因为我们不希望改变参数值,所以是 const 类型的

实现深拷贝的必要性

当执行下面的代码的时候,新对象 m 中的成员指针 和 旧对象 ml 中的成员指针都会指向 堆区空间字符串为 “ml”的地址,那么 ml 在结束的时候会调用析构函数释放掉该堆区空间,而 m 在结束的时候也会调用析构函数释放掉该堆区空间

Person ml("ml");
Person m = ml;  //深拷贝

所以上面的情况就是,新旧对象中的指针成员指向同一块堆区空间,于是新旧对象对同一块堆区空间释放掉了两次,造成了堆区空间的多次释放,这就是浅拷贝存在的问题

这个时候就需要使用到深拷贝,让新对象中的指针成员指向新的堆区空间,那么新旧对象释放的时候就不会多次释放同一块堆区空间,这就解决了浅拷贝存在的问题

//Person类中的深拷贝Person(const Person &ob){mName = new char [strlen(ob.mName)+1];   //新对象申请属于自己的堆区空间strcpy(mName,ob.mName);cout<<"有参构造:"<<ob.mName<<endl;}
#include <iostream>
#include <string.h>
#include <stdlib.h>using namespace std;
class Person
{
private:char *mName;
public://无参构造Person(){mName = NULL;}//有参构造Person(char *name){mName = new char [strlen(name)+1];   //申请堆区空间strcpy(mName,name);cout<<"有参构造:"<<mName<<endl;}//深拷贝Person(const Person &ob){mName = new char [strlen(ob.mName)+1];   新对象申请属于自己的堆区空间strcpy(mName,ob.mName);cout<<"有参构造:"<<ob.mName<<endl;}//析构函数~Person(){if(mName != NULL){delete [] mName;mName = NULL;cout<<"释放 Person 类的指针成员所指行向的 堆区空间"<<endl;}}
};int main(int argc, char *argv[])
{Person ml("ml");Person m = ml;  //深拷贝return 0;
}

3、注意事项

析构函数没有 void 和 返回值

如果用户定义了有参构造或者拷贝构造,都会屏蔽系统默认无参构造,所以这种情况最好是有自定义的无参构造,不会编译会出错

如果用户定义了有参构造或者无参构造,不会屏蔽拷贝构造

默认的拷贝都是浅拷贝(能完成基本的操作)

如果类中没有指针成员,不用实现构造拷贝和析构函数

如果类中有指针成员而且指向堆区空间,必须实现析构函数释放指针成员指向的堆区空间,必须实现拷贝构造完成深拷贝动作

相关文章:

析构函数、拷贝构造

1、析构函数析构函数的定义方式函数名和类名相同&#xff0c;在类名前加~&#xff0c;没有返回值类型&#xff0c;没有函数形参&#xff08;不能重载&#xff09;当对象生命周期结束的时候&#xff0c;系统会自动调用析构函数先调用析构函数&#xff0c;再释放对象的空间析构函…...

光学镜头是制作过程阶段理解

光学镜头是由多组镜片组合而成&#xff0c;它是摄影机投影一及显微镜上必不可少的部件。那么光学镜头是如何制造的呢&#xff1f;光学镜头的制作分为以下四个阶段&#xff1a;第一、首先将一大块光学玻璃用钻石锯片进行切片&#xff0c;然后用钻头在每一块玻璃切片上钻出多块冰…...

实验室设计|实验室设计要点SICOLAB

一、实验室设计规划要素1、实验室布局&#xff1a;实验室的布局要符合实验室工作流程&#xff0c;可以将实验室划分为干净区和污染区&#xff0c;以确保实验室的卫生和实验的准确性。2、设备选购&#xff1a;根据实验需要选择适当的设备&#xff0c;并确保设备的质量和性能符合…...

I.MX6ULL_Linux_系统篇(16) uboot分析-启动流程

原文链接&#xff1a;I.MX6ULL_系统篇(16) uboot分析-启动流程 – WSY Personal Blog (cpolar.cn) 前面我们详细的分析了 uboot 的顶层 Makefile&#xff0c;了解了 uboot 的编译流程。本章我们来详细的分析一下 uboot 的启动流程&#xff0c;理清 uboot 是如何启动的。通过对 …...

【C#】async关键字修饰后有无await的影响

文章目录测试总结拓展&#xff1a;js的async await问题参考测试 来自微软官网的说法&#xff1a; 异步方法通常包含 await 运算符的一个或多个匹配项&#xff0c;但缺少 await 表达式不会导致编译器错误。 如果异步方法未使用 await 运算符标记悬挂点&#xff0c;则该方法将作…...

Interspeech2022 | 一种基于元辅助学习的低资源口语语义理解方法

中国移动研究院首席科学家冯俊兰博士带领人工智能与智慧运营中心语音团队共同撰写的文章《Meta Auxiliary Learning for Low-resource Spoken Language Understanding》被语音国际顶会Interspeech2022接收。 关于Interspeech Interspeech 是国际最大且最全面关于言语科学与技…...

File类的用法和InputStream,OutputStream的用法

这里写自定义目录标题一、File类1.构造方法2.普通方法二、InputStream1.方法2.FileInputStream3.Scanner类的应用三、OutputStream1.方法2.FileOutputStream3.PrintWriter类的应用一、File类 1.构造方法 签名说明File(File parent, Stringchild)根据父目录 孩子文件路径&…...

Java多线程——Thread类的基本用法

一.线程的创建继承Thread类//继承Thread类class MyThread extends Thread{Overridepublic void run() {System.out.println("线程运行的代码");} } public class Demo1 {public static void main(String[] args) {MyThread t new MyThread();t.start();//启动线程&a…...

【C++】类和对象练习——日期类的实现

文章目录前言1. 日期的合法性判断2. 日期天数&#xff08;/&#xff09;2.1 和的重载2.2 对于两者复用的讨论3. 前置和后置重载4. 日期-天数&#xff08;-/-&#xff09;5. 前置- -和后置- -的重载6. 日期-日期7. 流插入<<重载8. 流提取>>重载9. 总结10. 源码展示前…...

[LeetCode周赛复盘] 第 333 场周赛20230219

[LeetCode周赛复盘] 第 333 场周赛20230219 一、本周周赛总结二、 [Easy] 6362. 合并两个二维数组 - 求和法1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6365. 将整数减少到零需要的最少操作数1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6364. 无平方子集计数1. 题目描…...

数字化时代,如何做好用户体验与应用性能管理

引言 随着数字化时代的到来&#xff0c;各个行业的应用系统从传统私有化部署逐渐转向公有云、行业云、微服务&#xff0c;这种变迁给运维部门和应用部门均带来了较大的挑战。基于当前企业 IT 运维均为多部门负责&#xff0c;且使用多种运维工具&#xff0c;因此&#xff0c;当…...

Python爬虫(7)selenium3种弹窗定位后点击操作,解决点击登录被隐藏iframe无法点击的登陆问题

之前的文章有关于更多操作方式详细解答&#xff0c;本篇基于前面的知识点进行操作&#xff0c;如果不了解可以先看之前的文章 Python爬虫&#xff08;1&#xff09;一次性搞定Selenium(新版)8种find_element元素定位方式 Python爬虫&#xff08;2&#xff09;-Selenium控制浏览…...

如何对项目健康度进行测量?评估项目健康状况

项目驱动变革&#xff0c;大部分公司逐步由运营驱动转变为项目驱动&#xff0c;带来更多重新和商业价值。对组织而言&#xff0c;从商业角度看&#xff0c;项目旨在推动组织从一个状态转到另一个状态&#xff0c;从而达成特定目标。项目的健康情况如何关乎项目和变革的成本&…...

美国原装二手keysight E4980A(安捷伦)2MHZ LCR表

Agilent E4980A、Keysight E4980A、LCR 表&#xff0c;20 Hz - 2 MHz E4980A 是 Agilent 的 2 MHz LCR 表。LCR表是一种电子测试设备&#xff0c;用于测量电子元件的电感&#xff08;L&#xff09;、电容&#xff08;C&#xff09;和电阻&#xff08;R&#xff09;。LCR 表可…...

《clean coder》:关于摆烂,争论和心态

“凡是不能在五分钟之内解决的争论&#xff0c;都不能依靠辩论解决” ---- Kent Beck 作为一个码农&#xff0c;我并不是一个喜欢争论的角色。很长一段时间会陷入一种摆烂的&#xff0c;被动的状态。“既然其他人想要这么做&#xff0c;就这么办吧”。这可能是非专业的行为中最…...

jenkins下载与简单使用

1.jenkins下载 因为我仍然使用的是jdk1.8进行开发&#xff0c;所以我下载的是jenkins2.332.1版本&#xff08;jenkins2.346.1版本在2022年末不再支持java8&#xff0c;如果项目使用的是jdk11可以继续使用该jenkins版本&#xff09;&#xff0c;更多版本下载请点击jenkins下载 …...

3|物联网控制|计算机控制-刘川来胡乃平版|第3章:计算机总线技术 补充串行总线部分|课堂笔记|ppt

2022年 10月 10日 3.3 外部总线 3.3.2 RS-232-C总线 机械特性...

Blazor入门100天 : 身份验证和授权 (3) - DB改Sqlite

目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 本节源码 https://github.com/…...

阅读源码和查看官方文档,是解决问题最高效的办法。

作为一个工作8年的老程序员告诉你&#xff1a;阅读源码和查看官方文档&#xff0c;是解决问题最高效的办法。不信你来看&#xff0c;这个困扰了读者半天的问题我查了源码和文档后瞬间解决。 前言 上周五有位读者私信我一个问题&#xff0c;说困扰了他半天&#xff0c;研究了一…...

云原生流量管理系统中 Service , Ingress 和 Endpoint 的关系

摘要 Kubernetes(简称 K8s)是一个用于容器编排和管理的开源平台,其中流量管理是 K8s 的重要功能之一。K8s 提供了多种流量管理方式,以便对不同场景下的流量进行控制和管理。以下是 K8s 中常用的流量管理系统: Service:Service 是 K8s 中最基本的流量管理方式,用于提供…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...