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

C++万物起源:类与对象(三)拷贝构造、赋值重载

目录

一、拷贝构造函数

1.1拷贝构造函数的概念与特征

1.2拷贝构造的实现

1.3默认构造函数

1.4拷贝构造函数典型调用场景

二、赋值运算符重载

2.1赋值运算符重载的格式


一、拷贝构造函数

1.1拷贝构造函数的概念与特征

在c语言语法中,我们可以将一个变量赋值给和它统一类型的变量,而在C++中,同样可以使用拷贝构造函数实现。

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

拷贝构造函数也是特殊的成员函数,其特征如下:

1. 拷贝构造函数是构造函数的一个重载形式。

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

1.2拷贝构造的实现

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// Date(const Date& d)   // 正确写法Date(const Date& d)   // 错误写法:编译报错,会引发无穷递归{_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);return 0;
}

注意:拷贝构造的参数必须用引用来接受,因为用户传过来的是一个对象,如果直接拿一个该类型的对象作为函数参数来进行接收,这个参数在接收被拷贝的对象时 就会去调用拷贝构造然后再将值传下去,这样就会引发无穷递归调用。

1.3默认构造函数

若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按
字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time(const Time& t){_hour = t._hour;_minute = t._minute;_second = t._second;cout << "Time::Time(const Time&)" << endl;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};
int main()
{Date d1;// 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数// 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数Date d2(d1);return 0;
}
在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定
义类型是调用其拷贝构造函数完成拷贝的。
编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?
当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

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

 

1.4拷贝构造函数典型调用场景

1.使用已存在对象创建新对象
2.函数参数类型为类类型对象
3.函数返回值类型为类类型对象
为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用
尽量使用引用。

二、赋值运算符重载

C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数,也具有其
返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号
函数原型:返回值类型 operator操作符(参数列表)。
注意:
不能通过连接其他符号来创建新的操作符:比如operator@
重载操作符必须有一个类类型参数
用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐
藏的this
1.*  2::  3sizeof 4? 5: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

2.1赋值运算符重载的格式

参数类型:const T&,传递引用可以提高传参效率
返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
检测是否自己给自己赋值
返回*this :要复合连续赋值的含义
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// bool operator==(Date* this, const Date& d2)// 这里需要注意的是,左操作数是this,指向调用函数的对象bool operator==(const Date & d2){return _year == d2._year;&& _month == d2._month&& _day == d2._day;}
private:int _year;int _month;int _day;
};
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};
赋值运算符只能重载成类的成员函数不能重载成全局函数
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};
// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)
{if (&left != &right){left._year = right._year;left._month = right._month;left._day = right._day;}return left;
}
// 编译失败:
// error C2801: “operator =”必须是非静态成员
原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现
一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值
运算符重载只能是类的成员函数。
用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注
意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符
重载完成赋值。
既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实
现吗?当然需要 如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。
比如之前的stack,如果不重载赋值,就会导致两个对象指向同一块空间,从而最后调用两次析构导致程序崩溃。

相关文章:

C++万物起源:类与对象(三)拷贝构造、赋值重载

目录 一、拷贝构造函数 1.1拷贝构造函数的概念与特征 1.2拷贝构造的实现 1.3默认构造函数 1.4拷贝构造函数典型调用场景 二、赋值运算符重载 2.1赋值运算符重载的格式 一、拷贝构造函数 1.1拷贝构造函数的概念与特征 在c语言语法中&#xff0c;我们可以将一个变量赋值给…...

JavaScript构造函数(new构造js对象与原型链prototype)

构造函数详解 铺垫&#xff1a;面向对象编程一、构造函数是什么&#xff1f;二、构造函数的作用&#xff1f;三、构造函数的执行过程&#xff1f;四、构造函数的返回值&#xff1f;五、构造函数为什么要用new关键字调用&#xff1f;六、构造函数的实例成员和静态成员&#xff1…...

【WPF应用31】WPF基本控件-ListView的详解与示例

WPF&#xff08;Windows Presentation Foundation&#xff09;是.NET框架的一个组成部分&#xff0c;它用于构建桌面应用程序的用户界面。ListView是WPF中一个非常强大的数据展示控件&#xff0c;它可以用来显示一系列的项&#xff0c;类似于Windows资源管理器中的文件列表。Li…...

【动态】江西省小型水库安全监测能力提升试点项目通过验收

近日&#xff0c;由北京国信华源科技有限公司和长江勘测规划设计研究有限责任公司联合承建的江西省小型水库安全监测能力提升试点项目圆满通过验收。 在项目业主单位的组织下&#xff0c;省项目部、特邀专家、县水利局二级项目部以及项目设计、监理、承建等单位的代表组成验收工…...

前视声呐目标识别定位(九)-声呐驱动

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 前视声呐目标识别定位&#xff08;三&#xff09;-部署至机器人 前视声呐目标识别定位&#xff08;四&#xff09;-代码解析之启动识别模块 …...

【详解】Windows系统安装Nginx及简单使用

【详解】Windows系统安装Nginx及简单使用 一、Nginx是什么&#xff1f; “Nginx 是一款轻量级的 HTTP 服务器&#xff0c;采用事件驱动的异步非阻塞处理方式框架&#xff0c;这让其具有极好的 IO 性能&#xff0c;时常用于服务端的反向代理和负载均衡。”Nginx 是一款 http 服…...

WebGPU vs. WebGL:前端图形技术的进化与数字孪生的崭新前景

在现代互联网时代&#xff0c;图形渲染在网页应用和数字孪生的开发中起着至关重要的作用。WebGL和WebGPU是两种前端图形技术&#xff0c;它们在处理图形和计算密集型任务时发挥着关键作用。本文将深入研究这两种技术&#xff0c;探讨它们的区别、WebGPU的优势&#xff0c;以及它…...

即刻体验 | 使用 Flutter 3.19 更高效地开发

我们已隆重推出全新的 Flutter 版本——Flutter 3.19。此版本引入了专为 Gemini 设计的新 Dart SDK、一个能让开发者对 Widget 动画实现精细化控制的全新 Widget&#xff0c;Impeller 更新带来的渲染性能提升、有助于实现深层链接的工具和对 Windows Arm64 的支持&#xff0c;以…...

Exchanger 怎么用J.U.C

Exchanger简介 Exchanger通常用来解决以下类似场景的问题&#xff0c;如下&#xff1a;两个线程间需要交换数据的问题&#xff0c;在多线程编程中&#xff0c;经常会有这样的场景&#xff1a;两个线程各自持有一些数据&#xff0c;并且需要在某个点上交换这些数据&#xff0c;…...

校园局域网钓鱼实例

Hello &#xff01; 我是"我是小恒不会java" 本文仅作为针对普通同学眼中的网络安全&#xff0c;设计的钓鱼案例也是怎么简陋怎么来 注&#xff1a;本文不会外传代码&#xff0c;后端已停止使用&#xff0c;仅作为学习使用 基本原理 内网主机扫描DNS劫持前端模拟后端…...

网络原理 - HTTP / HTTPS(3)——http响应

目录 一、认识 “状态码”&#xff08;status code&#xff09; 常见的状态码 &#xff08;1&#xff09;200 OK &#xff08;2&#xff09;404 Not Found &#xff08;3&#xff09;403 ForBidden &#xff08;4&#xff09;405 Method Not Allowed &#xff08;5&…...

Flask Python:模糊查询filter和filter_by,数据库多条件查询

数据库&#xff08;sqlalchemy&#xff09;多条件查询 前言一、filter、filter_by实现过滤查询1、filter_by()基础查询并且查询&#xff08;多条件查询&#xff09; 2、filter()like&#xff1a;模糊查询and&#xff1a;并且查询or&#xff1a;或者查询 二、all(),first(),get(…...

leetcode 热题 100(部分)C/C++

leetcode 热题 100 双指针 盛最多水的容器 【mid】【双指针】 思路&#xff1a; 好久没写代码sb了&#xff0c;加上之前写的双指针并不多&#xff0c;以及有点思维定势了。我对双指针比较刻板的印象一直是两层for循环i&#xff0c;j&#xff0c;初始时i,j都位于左界附近&…...

梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码

源码简介 最新梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码下载 梨花带雨播放器基于thinkphp6开发的XPlayerHTML5网页播放器前台控制面板,支持多音乐平台音乐解析。二开内容&#xff1a;修复播放器接口问题&#xff0c;把接口本地化&#xff0c;但是集成外链播放器…...

如何通过Spring提供的EL表达式执行bean的属性或方法?

如何通过Spring提供的EL表达式执行bean的属性或方法&#xff1f; 关键两个bean&#xff1a; org.springframework.expression.Expression org.springframework.expression.spel.support.StandardEvaluationContext 实例&#xff1a; import cn.hutool.extra.spring.Spring…...

SSTI 服务器端模板注入(Server-Side Template Injection)

1.【攻防世界】Web_python_template_injection {{}}是变量包裹标识符&#xff0c;里面存放的是一个变量&#xff0c;当你输入 http://61.147.171.105:55121/{{8*8}} 执行成功&#xff0c;说明存在模版注入。接下来&#xff0c;开始想办法编代码拿到服务器的控制台权限 。 首先…...

Vue.js---------Vue基础

能够说出Vue的概念和作用能够使用vue/cli脚手架工程化开发能够熟练Vue指令 一.vue基本概念 1.学习vue Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 渐进…...

力扣经典150题第一题:合并两个有序数组

目录 合并两个有序数组问题详解与解决方法1. 介绍2. 问题描述3. 解题思路4. 算法实现5. 复杂度分析6. 测试和验证7. 扩展如何处理特殊情况和边界条件&#xff1f;如何处理数组中可能存在的重复元素&#xff1f;如何优化算法以减少内存使用或提高执行效率&#xff1f; 8. 总结9.…...

Git:日志修改

一、问题描述 有小伙伴提出一个需求&#xff0c;为了满足某种需要&#xff0c;需要在Git日志中增加一条提交记录&#xff0c;并且需要指定提交时间。 比如&#xff0c;以下面这个only-allow项目为例&#xff0c;想在它的Git日志2023/9/26 19:08:08前插入一条2023/9/28 19:08:0…...

【数据库】MySQL InnoDB存储引擎详解 - 读书笔记

MySQL InnoDB存储引擎详解 - 读书笔记 InnoDB 存储引擎概述InnoDB 存储引擎的版本InnoDB 体系架构内存缓冲池LRU List、Free List 和 Flush List重做日志缓冲&#xff08;redo log buffer&#xff09;额外的内存池 存储结构表空间系统表空间独立表空间通用表空间undo表空间临时…...

GPT-2原理-Language Models are Unsupervised Multitask Learners

文章目录 前言GPT-1优缺点回顾GPT-1实验结果分析GPT-1缺陷分析 GPT-2训练数据OpenAI的野心预训练/微调的训练范式训练数据选择 模型结构和参数&#xff08;更大的GPT-1&#xff09;模型预训练训练参数 输入数据编码 总结 前言 首先强调一下&#xff0c;在看这篇文章之前&#…...

逆向案例十二——看准网企业信息json格式的信息

网址&#xff1a;【全国公司排行|排名榜单|哪家好】-看准网 打开开发者工具——刷新——网络——XHR——下滑页面加载新的页面——找到数据包 发现参数加密&#xff0c;返回的数据也进行了加密 按关键字在下方搜索 kiv进入第一个js文件 ctrlf打开文件里面的搜索框继续搜kiv找到…...

docker安装jenkins 2024版

docker 指令安装安装 docker run -d --restartalways \ --name jenkins -uroot -p 10340:8080 \ -p 10341:50000 \ -v /home/docker/jenkins:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker jenkins/jenkins:lts访问…...

输入url到页面显示过程的优化

浏览器架构 线程&#xff1a;操作系统能够进行运算调度的最小单位。 进程&#xff1a;操作系统最核心的就是进程&#xff0c;他是操作系统进行资源分配和调度的基本单位。 一个进程就是一个程序的运行实例。启动一个程序的时候&#xff0c;操作系统会为该程序创建一块内存&a…...

Linux(centos7)部署hive

前提环境: 已部署完hadoop(HDFS 、MapReduce 、YARN) 1、安装元数据服务MySQL 切换root用户 # 更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysqL-2022 # 安装Mysql yum库 rpm -Uvh http://repo.mysql.com//mysql57-community-release-el7-7.noarch.rpm # yu…...

LeetCode | 数组 | 双指针法 | 27. 移除元素【C++】

题目链接 1. 题目描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑…...

【Apache Doris】周FAQ集锦:第 2 期

【Apache Doris】周FAQ集锦&#xff1a;第 2 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…...

jQuery(二)

文章目录 1.jQuery操作节点1.查找节点&#xff0c;修改属性1.基本介绍2.切换图片案例 2.创建节点1.基本介绍2.内部插入3.外部插入4.小结1.插入方法说明2.两种插入方法的区别 5.插入元素实例6.移动元素实例 3.删除节点1.基本介绍2.代码实例 4.复制节点1.基本介绍2.代码实例 5.替…...

MIT6.828 实验环境安装教程

Thanks&#xff1a;mit6.828环境搭建 - 人云我不亦云的文章 - 知乎 https://zhuanlan.zhihu.com/p/489921553 sudo make && make install install -d -m 0755 "/share/qemu" install: 无法创建目录 “/share”: 权限不够 make: *** [Makefile:382&#xff1a…...

一文彻底搞清 Iterator(遍历器)概念及用法

目录 一、由来及意义 二、具体实现流程 三、具有默认 Iterator 接口的数据结构 四、调用 Iterator 接口的场合 五、总结 一、由来及意义 Javascript中表示“集合”的数据结构&#xff0c;主要是 Array、Object、Map、Set 这四种数据集合&#xff0c;除此之外&#xff0c;…...

为什么要建设学校网站/建材企业网站推广方案

模拟实现C智能指针shared_ptr和weak_ptr 仿写C的shared_ptr和weak_ptr 当强智能指针shared_ptr的引用计数为0时&#xff0c;析构资源 当弱智能指针weak_ptr的引用计数为0时&#xff0c;析构引用计数对象 #include<iostream> #include<new> #include<stdio.h&g…...

海沧网站建设/资源网

本文来源为node.js社区附上链接 http://cnodejs.org/topic/5231a630101e574521e45ef8 require 用来加载代码&#xff0c;而 exports 和 module.exports 则用来导出代码。但很多新手可能会迷惑于 exports 和 module.exports 的区别&#xff0c;为了更好的理解 exports 和 module…...

设置网站建设/报个计算机培训班多少钱

1,在电路中没有任何功能&#xff0c;只是在PCB上为了调试方便或兼容设计等原因。 2,可以做跳线用&#xff0c;如果某段线路不用&#xff0c;直接不贴该电阻即可&#xff08;不影响外观&#xff09; 3,在匹配电路参数不确定的时候&#xff0c;以0欧姆代替&#xff0c;实际调试…...

7月新闻大事件30条/深圳seo教程

真心不容易呀&#xff01;开源软件搭建挺麻烦的&#xff0c;各种组件未必要使用最新的版本&#xff1b;有些最新版本反而不兼容。需要仔细看官方说明书来进行搭建&#xff08;官方网站都是英文&#xff09;&#xff0c;所以闹得重新安装了几次。 先上测试用例通过的图&#xff…...

网站网站优化/长沙网站建设公司

1、什么是Mybatis&#xff1f;(1)Mybatis是一个半ORM(对象关系映射)框架&#xff0c;它内部封装了JDBC&#xff0c;开发时只需要关注SQL语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql&#xff0c;可以严格…...

做自媒体可以搬运国外网站新闻吗/最新域名8xgmvxyz

1)、新建ADO.NET实体数据模型--->选择空CodeFirst模型2)、新建两个实体类(客户表和订单信息表)usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel.DataAnnotations;usingSystem.ComponentModel.DataAnnotations.Schema;usingSystem.Linq;usingSystem…...