【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,一经查实,立即删除!

相关文章

后端python构网并生成纹理图片发回给cesium做贴地处理

在后端Python中&#xff0c;你可以使用一些库来进行网格构建和纹理生成&#xff0c;然后将生成的纹理图片发送给Cesium进行贴地处理。以下是一种可能的方法&#xff1a; 构建网格&#xff1a;使用点的坐标信息和索引信息&#xff0c;可以使用一些三角网格生成算法来构建网格。你…

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构建…

C++关联容器1——关联容器概述,map,set介绍,pair类型

关联容器 关联容器支持高效的关键字查找和访问。 两个主要的关联容器&#xff08;associative-container)类型是map和set。 map中的元素是一些关键字一值&#xff08;key-value&#xff09;对&#xff1a;关键字起到索引的作用&#xff0c;值则表示与索引相关联的数据。 se…

内网安全-代理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…

NodeJs入门知识

**************************************************************************************************************************************************************************** 1、配置Node.js与npm下载&#xff08;精力所致&#xff0c;必有精品&#xff09; …

算法--分治法

分治法是一种算法设计策略&#xff0c;它将一个复杂的问题分解成两个或多个相同或相似的子问题&#xff0c;直到这些子问题可以简单地直接解决。然后&#xff0c;这些子问题的解被合并以产生原始问题的解。 分治法通常遵循以下三个步骤&#xff1a; 分解&#xff1a;将原问题…

蓝桥杯-路径之谜

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

整数的表示和运算

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

前端初学者的 CSS 入门

文章导读&#xff1a;AI 辅助学习前端&#xff0c;包含入门、进阶、高级部分前端系列内容&#xff0c;当前是 CSS 的部分&#xff0c;瑶琴会持续更新&#xff0c;适合零基础的朋友&#xff0c;已有前端工作经验的可以不看&#xff0c;也可以当作基础知识回顾。 从这篇文章开始…

OneFlow深度学习框架入门与实践

OneFlow深度学习框架入门与实践 一、引言 在深度学习领域&#xff0c;框架的选择对于研究人员和开发者至关重要。OneFlow作为一款新兴的深度学习框架&#xff0c;凭借其高性能、易用性和灵活性&#xff0c;逐渐在业界崭露头角。本文将带领大家深入了解OneFlow深度学习框架&am…

Spark Stream

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

React 第十七章 Hook useRef

React中的useRef是一个Hook函数&#xff0c;它可以用来在函数组件中创建一个可变的引用。它类似于类组件中的ref属性&#xff0c;但有一些不同之处。 useRef可以用来保存任意可变值&#xff0c;而不仅仅是DOM元素的引用。它可以在函数组件的多次渲染之间保持不变。 使用useRe…

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…