构造析构理解与拷贝函数初识

1.        6个默认成员函数

----初始化和清理{        1.构造        2.析构        }

-----拷贝复制{        1.拷贝构造        2.赋值重载               }

------取地址重载{        1.普通对象        2.const对象取地址        }

注:构造函数的目的是初始化成员变量,而不是创造变量

析构函数的目的是清理需要清理的资源(指的是malloc,new,流,链接),而不是销毁变量

2.构造函数

1.分类:

        1.自己写

1.自己写带参构造或半缺省构造,必须通过外界传值初始化成员变量(非默认构造)

2.自己写无参构造或全缺省构造,可以不传参。例:实现栈可以全缺省让外界决定是否开始就确定容量。(默认构造)

(使用注意:1.在前面用public访问限定符修饰,因:默认private

                      2.一般无参构造和全缺省构造只写其一,因:外部调用不传参会构成歧义(是否重载与歧义无关)

                      3.初始化调用不需传参的不能写空括号,因:test n1(),类名+对象名+()与函数声明歧义。)

        2.默认生成

不写构造时,编译器会为你生成一个构造,默认生成的为公有的无参构造,编译器可能处理或不处理你的内置类型变量。(同C)。会调用你的自定义类型变量的默认构造,如果没有默认构造就报错。通过层层调用,直到全剩内置类型结束。(默认构造)

注意:关于自定义类型初始化处理,编译器无论在哪种情况下,都尝试调用此类型的默认构造,所以不必纠结,只当作  初始化外面类的对象时  要初始化其成员变量,内置类型不做处理,一旦初始化到了自定义类型,这个变量就会自己调用默认构造类型。(你无法在初始化外部对象时给内部自定义类型的要传参的构造函数传参,编译器不知道你给哪个传,也没有这个语法。)

例:外部类构造由编译器生成

外部构造由自己写

(验证编译器是否会调用内部自定类型默认构造函数与外部类型的构造无关,只要初始化到自定义类型了,就会调用)

2.默认构造的定义:

无需传参的构造函数:1.无参构造。2.全缺省参数构造。3.编译器生成的构造。

                                                (一般三者取其一)

3.总结:

什么时候用:

        1.缺省:涉及顺序表等可传参确定初始容量的,或其他可能在某些场景需要手动初始化特定值的。

        2.手动无参:内置类型需要初始化(也可以换为给内置类型变量给缺省值),或者需要动态开辟的。

        3.编译器构造:全为自定义类型,只需要在自定义类型里手动写构造,外部直接调。例子:双栈一类。

什么时候不用:

1.成员全是自定义类型,可以不用手写。(原因往上翻)(极少情况)

        内置类型少,不需外部给特殊值,给缺省值就行的,可以不用手写。

2.大多数需要通过各种方式初始化内部内置类型变量的要手写。

补充:给内置类型变量缺省值(C++11的补丁)

定义:在定义类型时就给予内置类型变量一个默认值。对象初始化时,其优先对其内容改变。

来源:编译器给的构造函数不能满足大部分程序员,C++委员会就新提供了一种给内置类型变量默认值的方式。

名称来源:

因为1.此时类没有任何一个空间已开辟,不能叫赋值,

2.而这种行为又可以通过构造函数覆盖使得默认值改变,

所以叫 给予变量缺省值。

使用注意:如果同时有构造和缺省值,类实例化(对象初始化)时,先给内置类型变量赋默认的缺省值,再调构造覆盖它。(编译器构造不会理睬已赋缺省值的变量)

3.析构函数

使用注意:由于析构函数一般由编译器调用(也可以自己调用,但编译器在这之后会自己调用一次,往往会造成许多错误:free两次同样的空间。。。),不允许传参,也就不允许重载,只能有一个析构。

1.编译器的析构:

唯一作用是对自定义类型变量调用其析构,内置类型不管。(本身对象要销毁,内变量都要销毁,到自定义类型变量销毁时,自然就会自己调用析构,不用纠结编译器析构的用处)

2.什么时候需要析构:

1.类里对成员变量有malloc,fopen,new,链接等操作的,需手动写

2.没有上述的,不用写。(内部自定义类型变量有....在变量类里写)

4.拷贝构造

1.属于

构造函数的一个重载形式,但编译器会在不写的情况下生成,也就是说一个类里至少会有两个构造。

拷贝构造十分特殊,需与构造区分。

2.作用

对象初始化时可以通过拷贝一个相同类的对象来初始化。

例子:1.将对象以实参形式传给形参(形参是实参的拷贝,会调用拷贝构造来初始化形参)

2.外部调用拷贝构造初始化一个一模一样的对象。

3.规定

参数只能是一个接受实参的同类引用

Qt:1.为什么不能是对象接受而是引用接受。

Ans:对象接受会造成无限递归调用,使用拷贝构造要传参,将实参对象给形参要调用拷贝构造拷贝,使用拷贝构造要传参......

(编译器这里会当作语法错误检查)。

Qt:2.为什么不能用指针接收?

Ans:指针是会达到与引用同样效果的,但是由于拷贝构造在1.对象间相互赋值 2.传参 时会自动调用拷贝构造,所以需要一定的格式,引用更为方便,所以编译器认为:指针做参数的构造不是拷贝构造。不会调用指针实现的拷贝效果。

4.分类

1.编译器默认生成的为浅拷贝,或叫值拷贝。

内置类型会按地址一字节一字节地拷贝给对象(值拷贝),内置类型会调用它的拷贝构造函数拷贝(可能是深拷贝或浅拷贝)。(同构造,层层调用)

2.自己写的,分为浅拷贝和深拷贝

1.浅拷贝 

只会把值拷贝给对应对象。

缺点:如果对象里有指针,那么两个对象的指针变量会指向同一块空间,空间被共享,而不是拷贝!

2.深拷贝

如果被拷贝对象里有一块空间,深拷贝后,新对象会自己另外申请一块空间。(必须手动完成)

图为栈的深拷贝。

3.什么时候要用深拷贝?

在类中有指针(包括数组)时:

1.外部以对象初始化另一对象时

2.对象赋值时

4.什么时候不用深拷贝?

没有指针就不用

1.形参接受不用(形参接收如果不需要改变值可以考虑const引用接收,节省成本还不用考虑被修改)

注:一般不写析构函数就不写拷贝构造,写了拷贝构造就要写(满足条件同,有指针或一些值指向资源,如:malloc,流,new)

5.初识运算符重载

引子:如果一个类为记录日期,怎么比较类的两个对象的日期先后。Date1>Date2外部可以这样实现吗?

定义:

为对象间的运算符赋予自己的含义。

摘自菜鸟教程

关键字:operator

语法:operator运算符 构成函数名,前加返回值,后加参数列表,当作正常函数在类中定义;

图为类外运算符重载,可以定义两个不同或同类对象运算符比较。

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

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

相关文章

珠海华发实业股份有限公司副总毛冰清莅临天府锋巢直播产业基地考察调研

3月19日,珠海华发实业股份有限公司副总毛冰清拜访天府锋巢直播产业基地(以下简称天府锋巢),由产业招商总负责人姜国东进行接待。 基地建设情况 姜国东负责人介绍到,天府锋巢是由德商产投携手无锋科技于兴隆湖落地的成都…

Tmux 使用笔记

Tmux 是一个终端复用器(terminal multiplexer),非常有用,属于常用的开发工具。 本文记录个人使用 Tmux的命令。 1. tmux简介 命令行的典型使用方式是,打开一个终端窗口,连接计算机,在里面输入…

Docker功能简单学习及使用

Docker是什么 Docker是一个快速构建,运行,管理应用的工具 传统基于linux安装程序较为复杂繁琐,使用docker可以快速的进行项目部署和管理 镜像与容器 Docker进行安装应用时,会自动搜索并下载应用镜像(image)。镜像不仅包含应用本…

每日一题 — 最大连续 1 的个数III

解法一:暴力枚举 先定义left和right双指针,left先固定在起始位置,遍历right当值等于1的时候,直接跳过,等于0的时候,zero计数器加一当zero等于k的时候,就开始记录此时最大长度是多少然后left加一…

Severt基本使用

severt是让我们自己写一些类,然后把这些类给加载Tomcat中,后续Tomcat收到HTTP请求(来自于浏览器),就会执行到咱们上面写的代码.从而通过这些代码,完成一定的业务逻辑. 创建项目 此处创建的是一种新的项目的形式称为Maven项目,Maven是Java 中的一个的构建…

【Leetcode每日一题】模拟 - 数青蛙(难度⭐⭐)(51)

1. 题目解析 题目链接:1419. 数青蛙 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 一、模拟青蛙叫声的基本逻辑 在模拟青蛙叫声的过程中,我们需要遵循一定的规则来判断何时青蛙会发出声音。…

每日一题(leetcode2529):正整数和负整数的最大计数--二分法

因为需要O(logn)的复杂度,所以考虑使用二分法,先找到负数里面的最大下标(初始值定为-1),再找到第一个正数的下标(初始值定为数组长度值)。最后求出个数并进行比较即可。 …

Netty 入门应用之Http服务WebSocket

Netty实现Http服务 主要的变化是在初始化器中引入了新的编解码器 一些创建的类作用和Netty HelloWorld的小demo一样我这里就不再次重复了 1、Http服务端代码 public class HttpServer {public static void main(String[] args) {// 创建Reactor// 用来管理channel 监听事件 …

Hot100【十一】:最大子数组和

// 定义dp:以i结尾的最大子数组和 dp[i] max(dp[i-1] nums[i],nums[i]) class Solution {public int maxSubArray(int[] nums) {// 1. 不需要特殊处理// 2. 定义dpint[] dp new int[nums.length];dp[0] nums[0];int maxResult nums[0];// 3. dp递推for (int i …

微服务面试题一

1.SOA、分布式、微服务之间有什么关系和区别? 分布式架构是指将单体架构中的各个部分拆分,然后部署不同的机器或进程中去,SOA和微服务基 本上都是分布式架构的SOA是⼀种⾯向服务的架构,系统的所有服务都注册在总线上,…

TLF9471 - High-Speed CAN FD Transceiver

1 框图描述 2 功能描述 CAN收发器被设计用来承受汽车应用的恶劣条件,并支持12V应用。   SBC的控制器区域网络(CAN)收发器部分在汽车和工业应用中提供高速(HS)差分模式数据传输(最高可达2Mbaud&#xff09…

【Java基础】BigDecimal使用避坑规范

BigDecimal使用 解决浮点型运算时,出现结果失真的问题,比如0.10.2 —示例— public class ErrorCase {public static void main(String[] args) {// 0.30000000000000004System.out.println(0.1 0.2);} }构造方法 把string转成BigDecimal把double转B…

备战蓝桥杯Day40 - 第11届python组真题 - C跑步锻炼

一、题目描述 二、思路 1、使用datetime库中的方法可以很好的解决这个问题。 2、定义起始时间和结束时间,判断是否是周一或者是1号,结果res加上相应的里程数。 3、最后输出 res 即为本题答案。 三、代码实现 import datetimestart datetime.date(2…

深度学习图像处理04:图像分类模型训练实战——动物分类

这篇博文不涉及理论知识,主要通过一个完整的深度学习模型训练流程,直观地了解深度学习图像分类任务。有关理论的部分,之前几篇博文已经涉及基础部分,之后也会对一些理论进行补充。 本文将结合代码,主要介绍三部分内容…

OpenHarmony应用编译 - 如何在源码中编译复杂应用(4.0-Release)

文档环境 开发环境:Windows 11 编译环境:Ubuntu 22.04 开发板型号:DAYU 200(RK3568) 系统版本:OpenHarmony-4.0-Release 功能简介 在 OpenHarmony 系统中预安装应用的 hap 包会随系统编译打包到镜像中&a…

SpringBoot常用注解及其使用示例

Spring Boot是一个用于快速构建Java应用程序的框架,它简化了Spring应用程序的创建和部署过程。 Spring Boot提供了很多注解,用于简化开发过程,提高开发效率。本文将介绍几个Spring Boot常用注解的使用案例,包括Controller、Reques…

c#获取Web.Config中的值出现的错误及解决办法

c#获取Web.Config中的值出现的错误及解决办法 1.错误提示 2.原因寻找 问题出在Web.Config文件中 <add key"mchid " value"1495103432"/>//mchid 后面不应该有空格图示如下&#xff1a; 3.改正代码如下&#xff1a; <?xml version"1.0…

022——设计通信帧格式

本期没想好怎么排版以流水账形式展示了 int tcp_server(int argc, char *argv[]) {int server_fd, client_fd; struct sockaddr_in server_addr, client_addr; socklen_t client_len sizeof(client_addr); char *ip_address argv[1]; int port atoi(argv[2]); // 创建T…

Capture One 23 Enterprise for Mac中文版 全面的图像处理工具

Capture One 23 Enterprise for Mac中文版一款专业的图像编辑和管理软件&#xff0c;具备强大的功能和工具&#xff0c;适用于摄影师、摄影工作室和专业用户。 软件下载&#xff1a;Capture One 23 Enterprise for Mac中文版下载 该软件为用户提供了全面的图像处理工具&#xf…

SpringCloudAlibaba-整合nacos(二)

目录地址&#xff1a; SpringCloudAlibaba整合-CSDN博客 一、nacos服务部分 1.下载nacos&#xff0c;并执行数据库脚本&#xff1a;nacos-mysql.sql 2.修改配置文件&#xff0c;配置mysql 3.启动nacos ./startup.sh -m standalone 4.访问&#xff1a;http://127.0.0.1:884…