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

C++构造和析构

欢迎来观看温柔了岁月.c的博客
目前
设有C++学习专栏
C语言项目专栏
数据结构与算法专栏
目前主要更新C++学习专栏,C语言项目专栏不定时更新
待C++专栏完毕,会陆续更新C++项目专栏和数据结构与算法专栏
一周主要三更,星期三,星期五,星期天,
感谢大家的支持

C++构造和析构

  • 构造函数
    • 特点
    • 构造函数的创建和使用
      • 有参构造函数
      • 无参构造函数
      • 关于new的构造函数
    • 析构函数
      • 特点
    • 拷贝构造函数
      • 特点
    • 深拷贝和浅拷贝
    • 匿名对象
    • 析构与构造调用的顺序

构造函数

特点

1.名字和类名相同
2.没有返回值
3.构造函数是用来构造对象,构造对象时候,必定调用构造函数
4.不写构造函数,存在一个默认的构造函数,默认的构造函数是无参的,所以可以构造无参对象
5.默认的构造函数可以删掉,通过delete可以删除默认的构造函数
6.显示使用默认的构造函数,用defalt做显示调用
7.通常构造函数是public
8.如果自己写了构造函数,系统的默认构造函数就会不存在
9.构造函数决定对象的长相(构造函数有几个参数,构造的对象就要有几个参数)
10.构造函数通常做的事情,就是给数据成员初始化。
11.构造函数也是函数,可以进行重载,也可以进行缺省
12.通过缺省和重载,可以创建各种彰显不同的对象


#include<iostream>
#include<string>using namespace std;class MM
{
public:MM() = default; //显示使用默认构造函数MM() = delete;  //删除默认的构造函数private:int age;string name;
};
int main()
{system("pause");return 0;
}

注意:如果一个类中的默认构造函数被删除的话,是不能够构造对象的。
在这里插入图片描述

构造函数的创建和使用

有参构造函数

#include<iostream>
#include<string>using namespace std;class MM
{
public:MM(int m_age, string m_name){age = m_age;name = m_name;}void printDate(){cout << age << "\t" << name << endl;}private:int age;string name;
};int main()
{MM mm(10, "温柔了岁月");  //构造函数有2个参数,所以这路必须也要有两个参数,创建对象的过程就是调用构造函数过程mm.printDate();system("pause");return 0;
}

无参构造函数

#include<iostream>
#include<string>using namespace std;class MM
{
public:MM();  //无参构造函数
private:int age;string name;
};
int main()
{MM mm;system("pause");return 0;

关于new的构造函数

#include<iostream>
#include<string>using namespace std;class MM
{
public:MM();  //无参构造函数MM(int m_age, string m_name){age = m_age;name = m_name;}private:int age;string name;
};
int main()
{MM *p1 = new MM; //无参构造函数MM* p2 = new MM(18, "温柔了岁月"); //有参的构造函数system("pause");return 0;
}

析构函数

特点

1.~类名,当作析构函数的名称
2.没有参数
3.释放数据成员new的内存
在对象死亡前,自动调用
4.如果数据成员没有做new的操作,可以不写析构函数,不写析构函数,系统存在一个默认的析构函数

//析构函数
#include<iostream>
#include<cstring>using namespace std;class MM
{
public:MM(const char * str){int length = strlen(str) + 1;name = new char[length];strcpy(name, str);}~MM(){if (name != nullptr){delete name;name = nullptr;}cout << "析构函数" << endl;}private:char* name;
};
int main()
{MM* pmm = new MM("温柔了岁月");delete pmm;pmm = nullptr;  //立刻调用析构函数system("pause");return 0;
}

拷贝构造函数

特点

1.拷贝构造函数也是构造函数
2.拷贝构造函数的参数是固定的:对对象的引用
3.拷贝构造函数不写,会存在一个默认的拷贝构造函数
4.拷贝构造函数的作用:通过一个对象,创造另一个对象。

#include<iostream>
#include<string>using namespace std;class MM
{
public:MM(int m_age){age = m_age;}//拷贝构造函数,通过传入对象属性,确定创建对象属性MM(MM& object){age = object.age;}void printDate(){cout << age << endl;}private:int age;
};
//函数传参也可以隐式调用
void print(MM object)
{object.printDate();
}void Print(MM& object) //引用只是取别名,不调用拷贝构造函数,效率较高
{object.printDate();
}int main()
{MM mm(10);//产生对象MM pmm = mm;  //隐式构造MM pm(mm); //显式构造print(mm); //隐式调用拷贝构造函数system("pause");return 0;
}

深拷贝和浅拷贝

浅拷贝:
没有在拷贝构造函数中,使用new
默认的拷贝构造函数都是浅拷贝
深拷贝:
在拷贝构造函数中做了new的操作
内存释放问题:
浅拷贝会导致同一段内存重复释放

//浅拷贝问题

#include<iostream>
#include<cstring>using namespace std;class MM
{
public:MM(const char* m_name){name = new char[strlen(m_name) + 1];strcpy(name, m_name);}MM(MM& object){name = object.name;}~MM(){if (name != nullptr){delete name;name = nullptr;}}private:char* name;
};
int main()
{MM mm("温柔了岁月");MM pmm = mm;return 0;
}

在这里插入图片描述

delete把相同的两端数据都删除了,所以程序中断,浅拷贝的问题,要用深拷贝来解决。

解决方法

#include<iostream>
#include<cstring>using namespace std;class MM
{
public:MM(const char* m_name){name = new char[strlen(m_name) + 1];strcpy(name, m_name);}MM(MM& object){int length = strlen(object.name) + 1;name = new char[length];strcpy(name, object.name);}~MM(){if (name != nullptr){delete name;name = nullptr;}}private:char* name;
};
int main()
{MM mm("温柔了岁月");MM pmm = mm;return 0;
}

一旦类中有指针,做了内存申请,并且对对象做了拷贝操作,就必须使用深拷贝

匿名对象

1.匿名对象就是无名对象,匿名对象只能充当右值,
2.如果做特殊处理,会直接死掉,要想对匿名对象赋初值,必须存在移动构造拷贝或者有const存在的普通拷贝构造。

#include<iostream>using namespace std;class MM
{
public:MM(int m_age){age = m_age;}void printDate(){cout << age << endl;}MM(MM&& object){age = object.age;cout << "调用移动构造" << age << endl;}~MM(){cout << "析构函数" << endl;}
private:int age;
};int main()
{MM(10);  //匿名对象没有名字MM girl = MM(10); //赋值对象, girl接管匿名对象的所有权girl.printDate();system("pasuse");return 0;
}

析构与构造调用的顺序

1 . 一般情况,构造顺序和析构顺序是相反的
2.全局和静态变量,最后释放的
3.delete会立刻调用析构函数

相关文章:

C++构造和析构

欢迎来观看温柔了岁月.c的博客 目前 设有C学习专栏 C语言项目专栏 数据结构与算法专栏 目前主要更新C学习专栏&#xff0c;C语言项目专栏不定时更新 待C专栏完毕&#xff0c;会陆续更新C项目专栏和数据结构与算法专栏 一周主要三更&#xff0c;星期三&#xff0c;星期五&#x…...

docker安装即docker连接mysql(window)

一 安装docker 1.什么是docker Docker容器与虚拟机类似&#xff0c;但二者在原理上不同。容器是将操作系统层虚拟化&#xff0c;虚拟机则是虚拟化硬件&#xff0c;因此容器更具有便携性、高效地利用服务器。 2.WSL2 WSL&#xff0c;即Windows Subsystem on Linux&#xff0c;中…...

HMM-维特比算法

HMM-维特比算法&#xff08;viterbi&#xff09;HMM回顾隐马科夫链解法&#xff1a;维特比算法&#xff08;Viterbi&#xff09;HMM回顾 最终的公式可以解释主要分为两个部分&#xff1a; P(xi|yi)&#xff0c;发射概率&#xff0c;字面意思是从一个词性中发射/生成出某一个单…...

【C++初阶】2. 类和对象_1

1. 面向过程和面向对象的初步认识 2. 类的引入 C语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定义函数。比如&#xff1a; 之前在数据结构初阶中&#xff0c;用C语言方式实现的栈&#xff0c;结构体中只能定义变量&#…...

kotlin把函数作为参数转递给另一个函数

kotlin把函数作为参数转递给另一个函数 fun say(s: String, foo: (String) -> Unit) {print("hello")foo(s) }fun hi(str: String) {println(str) }fun main(args: Array<String>) {say("hello", ::hi) } 输出&#xff1a; hellohello...

海思嵌入式开发-005-OpenHarmony源码编译问题

海思嵌入式开发-005-OpenHarmony源码编译问题一、问题描述二、解决方案2.1解决原理2.2获取OpenHarmony 3.1.1 Release源码2.3最后解决问题&#xff0c;编译成功。一、问题描述 按照链接拉取master源码&#xff0c;出现如下问题&#xff0c;打开build.log文件 提示相应位置的文…...

指针的进阶续(笔试题强化练习)

写在前面&#xff1a;在上次我们学习了指针的相关类型的知识&#xff0c;对指针家族的成员基本有了了解&#xff0c;这次让我们跟着一些题目来练习和补充一些知识&#xff0c;这有助于我们强化理解这些知识。 话不多说&#xff0c;我们马上开始&#xff1a; 1.指针和数组的笔…...

一个供参考的计算机的学习路线

本文是介绍如何成为一个Geek&#xff0c;一个真正的计算机高手。 适合有成为IT领域技术大牛的人参考。 写给大一新生和所有向深耕IT领域的人&#xff0c;避免走一些弯路。 仅代表个人想法&#xff0c;供批判性参考。 第一门入门的必备功课-语法与算法 什么是计算机&#xff1f…...

React(五):受控组件、高阶组件、Portals、Fragment、CSS的编写方式

React&#xff08;五&#xff09;一、受控组件1.什么是受控组件&#xff08;v-model&#xff09;2.收集表单数据:input和单选框3.收集表单数据:下拉框二、非受控组件三、高阶组件1.什么是高阶组件2.高阶组件的应用13.高阶组件的应用2-注入Context4.高阶组件的应用3-登录鉴权5.高…...

MATLAB——系统环境

MATLAB概述MATLAB的发展MATLAB:MATrix LABoratory1980年前后&#xff0c;Cleve Moler教授编写的Linpack 和Eispack的接口程序。1984年&#xff0c;MATLAB第1版(DOS版)1992年&#xff0c;MATLAB4.0版1994年&#xff0c;MATLAB 4.2版1997年&#xff0c;MATLAB 5.0版1999年&#x…...

2 GateWay工作流程+GateWay搭建

GateWay工作流程GateWay搭建 核心流程图如下&#xff1a; 核心概念&#xff1a; 客户端向 Spring Cloud Gateway 发出请求。如果Gateway Handler Mapping确定请求与路由匹配&#xff0c;则将其发送到Gateway Web Handler 处理程序。此处理程序通过特定于请求的Fliter链运行请求…...

【微信小程序】富文本rich-text的图片预览效果的几种方法

前言 使用原生小程序开发&#xff0c;实现在富文本rich-text中的图片预览效果的几种方法对比。 1.正则wx.previewImage&#xff08;有明显不足&#xff09; 一个不需要用额外组件或插件的方法&#xff1a; 思路&#xff1a;使用正则把图片的url进行剖离出来&#xff0c;push…...

通信网络-Socket、Java中的网络支持、多线程服务器

前言 通信网络-Socket、Java中的网络支持、多线程服务器 场景&#xff1a;使用java网络创建一个聊天室 博客地址&#xff1a;芒果橙的个人博客 文章目录前言通信网络-SocketTCP/IPTCP/IP 模型端口Java中的网络支持概念1. InetAddress2. URL3. Socket4. Datagram多线程服务器应用…...

搞懂 JS this、call、apply、bind

搞懂 JS this、call、apply、bind javascript 的 this ECMAScript 规范中这样写&#xff1a; this 关键字执行为当前执行环境的 ThisBinding。 MDN 上这样写&#xff1a; In most cases, the value of this is determined by how a function is called. 在绝大多数情况下&…...

力扣209长度最小的子数组

209. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xf…...

【mysql是怎样运行的】-InnoDB数据页结构

文章目录1. 数据库的存储结构&#xff1a;页1.1 磁盘与内存交互基本单位&#xff1a;页1.2 页结构概述1.3 页的上层结构2. 页的内部结构2.1 第1部分&#xff1a;文件头部和文件尾部2.1.1 File Header&#xff08;文件头部&#xff09;&#xff08;38字节&#xff09;2.1.2 File…...

VIM实用指南(10)语法自动补全插件coc.nvim

最近发现了一个新的自动补全插件coc.nvim异步&#xff0c;nodejs后端&#xff0c;配合它自身的lsp支持用起来非常舒服&#xff0c;同样也支持lsp和snippets&#xff0c;强烈推荐&#xff0c;值得一试。 1、使用vimplug安装插件 1.进入coc.nvim 在github的主页https://github.…...

【Vue3 第二十二章】过渡动画

一、基本用法 <Transition> 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-…...

【linux】:进程状态(僵尸进程等)以及环境变量

文章目录 前言一.进程状态 进程的优先级二.环境变量总结前言 本篇文章是接着上一篇【linux】:进程概念的后续&#xff0c;对于有基础的同学可以直接看这篇文章&#xff0c;对于初学者来说强烈建议大家从上一篇的概念开始看起&#xff0c;上一篇主要解释了冯诺依曼体系以及操…...

【C语言——练习题】指针,你真的学会了吗?

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨一维数组练习题&#xff1a;字符数组练习题&#xff1a;字符指针练习题&#xff1a;二维数组练习题&am…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...