【Cpp】类和对象#拷贝构造 赋值重载

标题:【Cpp】类和对象#拷贝构造 赋值重载

@水墨不写bug


目录

(一)拷贝构造

(二)赋值重载

(三)浅拷贝与深拷贝


正文开始:

(一)拷贝构造

        拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰,防止在拷贝的时候  被拷贝的对象  被修改),在用已存在的 类型对象 创建新对象时由编译器自动调用

1. 拷贝构造函数是构造函数的一个重载形式。
2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

#include<string>
using namespace std;
class Person
{
public:Person(char* name, int age = 0){_name = (char*)malloc(strlen(name)+1);_name = name;_age = age;}Person(Person& p)//拷贝构造必须是类对象的引用,否则会引发无穷递归{_name = (char*)malloc(strlen(p._name) + 1);_name = p._name;_age = p._age;}
private:char* _name;int _age;
};
int main()
{Person p1((char*)"zhangsan",35);Person p2(p1);return 0;
}


3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。


        注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。


4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?

        对于编译器自己生成的拷贝构造,是浅拷贝,只能完成对内置类型的拷贝,因为内置类型的本质就是一个值,或者说就是几个直接携带信息的数据。

        但是对于自定义类型,其本身指向的地址才是有效的数据,它间接指向有效的数据,对它本身进行浅拷贝没有实际意义。

        由于编译器自动生成的拷贝构造会只完成浅拷贝所以这时候就需要自己手动显示实现自定义类型的深拷贝。


5. 拷贝构造函数典型调用场景:
        使用已存在对象创建新对象
        函数参数类型为类 类型对象(也就是普遍的以类对象传参的情况)
        函数返回值类型为类类型对象

实例:

class Person
{
public:Person(char* name, int age = 0){_name = (char*)malloc(strlen(name)+1);_name = name;_age = age;}Person(Person& p)//函数参数类型为类 类型对象(也就是普遍的以类对象传参的情况){_name = (char*)malloc(strlen(p._name) + 1);_name = p._name;_age = p._age;}Person& Modefy()//修改人的信息,返回Person这个修改后的类对象{}private:char* _name;int _age;
};
int main()
{Person p1((char*)"zhangsan",35);Person p2(p1);//使用已存在对象创建新对象return 0;
}

        为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。

        注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。

(二)赋值重载

         C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

        函数名字为:关键字 operator(后面接需要重载的运算符符号)


        函数原型:返回值类型   operator操作符(参数列表)

实例:

Date& operator==(Date& d1)
{//...
}

注意
        不能通过连接其他符号来创建新的操作符:比如operator@ (不能创造操作符)
        重载操作符必须有一个类类型参数 (对于内置类型的操作符重载没有意义,因此只能对自定义类型的操作符重载)
        用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
        作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this


        . (浮点)/   *(解引用)/    ::(域作用限定符)/    sizeof(计算类型大小操作符)   /   ?:(三目操作符)    注意以上5个运算符不能重载。

1. 赋值运算符重载格式


        参数类型:const T&,传递引用可以提高传参效率(同时防止对象被修改)
        返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
        检测是否自己给自己赋值
        返回*this :要复合连续赋值的含义


2. 赋值运算符只能重载成类的成员函数,不能重载成全局函数


        原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。


3. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。

        注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。


4.既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实现吗?

        类似的,内置类型自己本身就直接携带信息,可以直接拷贝;但是自定义类型的直接浅拷贝是没有意义的;所以对于自定义类型,我们需要自己手动显示实现赋值重载,内置类型则不需要。

      注意:如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。

(三)浅拷贝与深拷贝

        浅拷贝和深拷贝是两种不同的拷贝方式,用于在编程中复制数据。

        浅拷贝是创建一个新的对象,新对象的内容与原对象相同,但是新对象中的引用类型的成员仍然指向原对象中的引用类型对象。换句话说,浅拷贝只是复制了对象的引用而已当原对象中的引用类型成员发生变化时,新对象中的引用类型成员也会随之变化。

        深拷贝是创建一个全新的对象,将原对象的所有成员(包括值类型和引用类型)逐一复制到新对象中。换句话说,深拷贝会复制对象中的引用类型,并创建一个新的引用类型对象。当原对象中的引用类型成员发生变化时,新对象中的引用类型成员不会随之变化。

        浅拷贝和深拷贝的区别在于对于引用类型成员的处理方式。浅拷贝只复制引用,而深拷贝会创建新的引用类型对象。

举一个例子:

        创建一个栈的对象stack_1;

        拷贝构造一个stack_2;

        如果使用的是编译器默认生成的浅拷贝方式,那么对 stack_2的操作本质上也就是对stack_1的操作,因为栈的底层是一个动态开辟的堆区数组,创建stack_2时因为浅拷贝只是拷贝了栈区上stack_1的指向堆的一个指针。因而两个栈指向的同一块堆上的数组。

        深拷贝则是在堆上重新开辟了一个数组,并把stack_1的值赋给stack_2。

 



完~

未经作者同意禁止转载 

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

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

相关文章

UG NX二次开发(C#)-获取Part中对象创建时的序号(*)

文章目录 1、前言2、UG NX的对象序号讲解3、采用UG NX二次开发或者建模序号4、注意事项1、前言 在UG NX中,我们创建任意一个对象,都会在模型历史中添加一个创建对象的编号,即是对象序号,这个是递增的,当删除中间产生的对象时,其序号会重新按照建模顺序重新排布。今天一个…

MLP实现fashion_mnist数据集分类(2)-函数式API构建模型(tensorflow)

使用函数式API构建模型&#xff0c;使得模型可以处理多输入多输出。 1、查看tensorflow版本 import tensorflow as tfprint(Tensorflow Version:{}.format(tf.__version__)) print(tf.config.list_physical_devices())2、fashion_mnist数据集分类模型 2.1 使用Sequential构建…

内网安全-代理Socks协议路由不出网后渗透通讯CS-MSF控制上线简单总结

我这里只记录原理&#xff0c;具体操作看文章后半段或者这篇文章内网渗透—代理Socks协议、路由不出网、后渗透通讯、CS-MSF控制上线_内网渗透 代理-CSDN博客 注意这里是解决后渗透通讯问题&#xff0c;之后怎么提权&#xff0c;控制后面再说 背景 只有win7有网&#xff0c;其…

26 JavaScript学习:JSON和void

JSON 英文全称 JavaScript Object NotationJSON 是一种轻量级的数据交换格式。JSON是独立的语言JSON 易于理解。 JSON 实例 简单的 JSON 字符串实例: "{\"name\": \"Alice\", \"age\": 25, \"city\": \"San Francisco\&…

PX4二次开发快速入门(三):自定义串口驱动

文章目录 前言 前言 软件&#xff1a;PX4 1.14.0稳定版 硬件&#xff1a;纳雷NRA12&#xff0c;pixhawk4 仿照原生固件tfmini的驱动进行编写 源码地址&#xff1a; https://gitee.com/Mbot_admin/px4-1.14.0-csdn 修改 src/drivers/distance_sensor/CMakeLists.txt 添加 add…

Servlet详解(从xml到注解)

文章目录 概述介绍作用 快速入门Servelt的执行原理执行流程&#xff1a;执行原理 生命周期概述API 服务器启动&#xff0c;立刻加载Servlet对象(理解)实现Servlet方式(三种)实现Servlet接口实现GenericServlet抽象类&#xff0c;只重写service方法实现HttpServlet实现类实现Htt…

蓝桥杯-路径之谜

题目描述 小明冒充X星球的骑士&#xff0c;进入了一个奇怪的城堡。城堡里面什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡的地面时n*n个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或者纵向移动&#xff0c;但是不能斜着走&#x…

整数的表示和运算

目录 无符号整数 有符号整数 原码表示 原码的缺点 原码-->反码-->补码的转换 原码,补码快速转换技巧(手算) 补码的加法计算 补码的减法计算 总结 无符号整数 无符号整数,即"自然数",0,1,2,3,4,.... C语言中的无符号整数: unsigned short a 1; //无符…

Spark Stream

一、Spark Streaming是什么 Spark Streaming 用于流式数据的处理。Spark Streaming 支持的数据输入源很多&#xff0c;例如&#xff1a;Kafka、Flume、Twitter、ZeroMQ 和简单的 TCP 套接字等等。数据输入后可以用 Spark 的高度抽象原语如&#xff1a;map、reduce、join、wind…

C++ | Leetcode C++题解之第67题二进制求和

题目&#xff1a; 题解&#xff1a; class Solution { public:string addBinary(string a, string b) {string ans;reverse(a.begin(), a.end());reverse(b.begin(), b.end());int n max(a.size(), b.size()), carry 0;for (size_t i 0; i < n; i) {carry i < a.siz…

算法学习系列(五十五):背包模型(三)

目录 引言一、潜水员二、背包问题求具体方案三、机器分配四、开心的今明五、金明的预算方案 引言 今天介绍的是背包模型&#xff0c;还是以题目的形式来介绍的。主要讲了背包问题求方案&#xff0c;就是由最优方案递推回去即可。还有就是一些比较经典的背包问题&#xff0c;其…

im即时通讯源码/仿微信app源码+php即时通讯源码带红包+客服+禁言等系统php+uniapp开发

即时通讯(IM)系统是现代互联网应用中不可或缺的一部分&#xff0c;它允许用户进行实时的文本、语音、视频交流。随着技术的发展&#xff0c;IM系统的功能越来越丰富&#xff0c;如红包、客服、禁言等。本文将探讨如何使用PHP语言开发一个功能完备的即时通讯系统&#xff0c;包括…

逻辑漏洞:Cookie脆弱性导致的逻辑漏洞

前几天学习了逻辑漏洞中的越权漏洞和支付漏洞&#xff0c;今天学习一下cookie脆弱性导致的逻辑漏洞 还是和之前一样&#xff0c;所有内容都是参考别的大佬总结好的&#xff0c;我只是在这里进行学习练习 1、cookie介绍 用户在客户端 (一般为浏览器) 中访问某个页面 &#xff0…

电脑崩溃了,之前备份的GHO文件怎么恢复到新硬盘?

前言 之前咱们说到用WinPE系统给电脑做一个GHO镜像备份&#xff0c;这个备份可以用于硬盘完全崩溃换盘的情况下使用。 那么这个GHO镜像文件怎么用呢&#xff1f; 咱们今天详细来讲讲&#xff01; 如果你的电脑系统硬盘崩溃了或者是坏掉了&#xff0c;那么就需要使用之前备份…

华为机考入门python3--(20)牛客20- 密码验证合格程序

分类&#xff1a;字符串 知识点&#xff1a; 遍历字符串的每个字符 for char in my_str: 可以直接比较字符范围 a < char < z 列表统计元素个数 my_list.count(elem) 寻找子串 my_str.find(sub_str) 题目来自【牛客】 import re import sysdef check_…

【算法】唯一分解定理及最lcm和gcd关系 宝石组合

前言 今天在做一道宝石组合的题目时了解到了这个定理&#xff0c;还是蛮有意思的。 思想 唯一分解定理&#xff1a; 对于任何正整数n&#xff0c;有 n p 1 a 1 p 2 a 2 . . . p k a k n p_1^{a1} \times p_2^{a2} \times ... \times p_k^{ak} np1a1​p2a2​...pkak​ …

C语言零基础快速入门视频教程

C语言零基础快速入门视频教程 介绍C语言C语言零基础视频教程领取教程下期更新预报 介绍C语言 C语言零基础快速入门&#xff1a;探索C语言的起源、特性与魅力 在编程世界中&#xff0c;C语言犹如一座古老而坚实的桥梁&#xff0c;连接着计算机科学的过去与现在。作为一门历史悠…

家庭用水安全新举措:保障自来水管和储水设施卫生

随着公众对家庭用水安全意识的提高&#xff0c;如何确保自来水管和楼顶储水罐的安全性和卫生已成为家庭生活中的重要议题。近期&#xff0c;专家针对此问题提出了一系列实用的注意事项和建议。 注意事项&#xff1a; 定期检查&#xff1a;专家强调&#xff0c;家庭应每季度至…

分布式事务—> seata

分布式事务之Seata 一、什么是分布式事务&#xff1f; 分布式事务是一种特殊类型的事务&#xff0c;它涉及多个分布式系统中的节点&#xff0c;包括事务的参与者、支持事务的服务器、资源服务器以及事务管理器。 在分布式事务中&#xff0c;一次大型操作通常由多个小操作组成…

如何查公网IP?

在网络通信中&#xff0c;每个设备都被分配一个独特的IP地址&#xff0c;用于在Internet上进行标识和通信。公网IP是指可以直接从Internet上访问的IP地址&#xff0c;也称为全局IP。通过查公网IP&#xff0c;我们可以了解我们的设备在Internet上的位置和连接状态。 2. 查公网IP…