C++ 拷贝构造函数和重载赋值运算符的区别
文章目录
- 拷贝构造函数
- 重载赋值运算符
赋值运算符和拷贝构造函数最大区别是赋值运算符没有新的对象生成,而拷贝构造函数会生成新的对象。
为了更加形象 准确得描述 赋值运算符和拷贝构造函数得区别,将详细通过代码展示两者之间得差异。
拷贝构造函数
首先从构造函数说起,在C++面向对象的设计中,每一个对象代表一个抽象集合的实体,此时每一个实体在当前运行的进程中是需要对应的内存空间,即对象存在则有空间。为此,C++引入构造函数来实例化对象,并让编译器为该对象向操作系统申请对应的空间,从而能够存在于操作系统之中。
拷贝构造函数则是为了将老对象的数据成员一一赋值给新的对象数据成员的一种构造函数,即拷贝构造函数的结果和构造函数一致,都是有新的对象生成。
查看如下代码:
#include <iostream>
using namespace std;class A{
public:A(){ cout << "default constructor " << endl; }A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){cout << this->num << endl;}private:int num;};
void para_copy(A &a)
{
}
int main()
{A a(100); // 重载构造函数A a1=a; //拷贝构造函数a1.print();A c;//默认构造函数return 0;
}
输出如下:
constructor with param //a 重载构造
copy constructor //a1 拷贝构造
100
default constructor //c默认构造
destructor 0 //c析构
destructor 100 //a1析构
destructor 100 //a析构
拷贝构造函数调用场景如下:
- 我们如上代码中 一个对象由另一个对象来初始化
- 对象作为函数参数
- 对象作为函数返回值
关于对象作为函数参数以及返回值时调用的拷贝构造函数,查看代码如下
输出如下#include <iostream> using namespace std;class A{ public:A(){ cout << "default constructor " << endl; }A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){cout << this->num << endl;}private:int num;}; void param_copy(A a) {cout << "param obj" << endl; } A return_value() {A d(0);cout << "return obj" << endl;return d; } int main() {A c;param_copy(c);return_value();return 0; }
default constructor //c 默认构造 copy constructor // 对象做参数,拷贝构造到临时对象 param obj destructor 0 // 析构掉临时对象 constructor with param //函数return_value中 d 对象使用了重载构造函数 return obj destructor 0 //析构掉 d对象 ,局部变量 destructor 0 //析构掉 c对象
关于深拷贝和浅拷贝的描述如下:
通常,默认生成的拷贝构造函数和赋值运算符,只是简单的进行值的复制。如果类的数据成员有指针,仅仅通过值传递进行拷贝构造的话会造成两个对象的成员指针指向同一块内存,当两个对象析构的时候会对同一个内存释放两次,从而会造成指针空悬。
深拷贝即以上第二种情况,数据成员中有指针变量的时候拷贝构造函数使用深拷贝,即构造函数中重新指定初始化对象的地址空间。
代码如下:
#include <iostream> using namespace std;class A{ public:A(){ p=new int(10);cout << "default constructor " << endl; }//A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;p=new int(10);*p=*(a.p);cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){if(p!=NULL){delete p;cout << this->num << endl;}}private:int num;int *p;}; void param_copy(A a) {cout << "param obj" << endl; } int main() {A c;A b(c);return 0; }
重载赋值运算符
赋值运算符和拷贝构造函数最大区别即是赋值运算符没有新的对象生成,而拷贝构造函数会生成新的对象。
#include <iostream>
using namespace std;class Person
{
public:Person(){}Person(const Person& p){cout << "Copy Constructor" << endl;}Person& operator=(const Person& p){cout << "Assign" << endl;return *this;}private:int age;string name;
};void f(Person p)
{return;
}Person f1()
{Person p;return p;
}int main()
{Person p;Person p1 = p; // Acout <<" p1 addr " << &p1 << endl;Person p2;cout <<" p2 addr " << &p2 << endl;p2 = p; // Bcout <<" p2 addr after asign " << &p2 << endl;f(p2); // C f函数参数cout <<" p2 addr after asign " << &p2 << endl;p2 = f1(); // D f1返回值为改对象,则先进行拷贝构造,在将返回的对象赋值给p2cout <<" p2 addr after asign " << &p2 << endl;Person p3 = f1(); // E 生成新对象,则为拷贝构造函数cout <<" p3 addr " << &p3 << endl;getchar();return 0;
}
输出如下:
Copy Constructor
Assign
Copy Constructor
Copy Constructor
Assign
Copy Constructor
相关文章:

单元格内多个姓名拆分成一列_EXCEL拆分单元格中的姓名,这都不叫事儿
作者:祝洪忠 转自:Excel之家ExcelHome小伙伴们好啊,今天老祝和大家来分享一个数据整理的技巧。下面的表格形式,想必大家不会陌生吧:在这个表格内,同一个部门的人员名单都挤到一个单元格内。现在问题来了&am…
3.1 A Historical Perspective 历史观点
1.从1978年的8086到现在的2008年core i7 ,从29K个晶体管到781M个晶体管,地址线(也叫地址位长(bit long))8086只有20个地址线,1982年,MS-windows 使用80286平台开发了自己的windows。直到1985年,i386正式扩展…

idea中 maven打包时时报错User setting file does not exist C:\Users\lenevo\.m2\setting.xml,
第一种错误 :idea中 maven打包时时报错User setting file does not exist C:\Users\lenevo\.m2\setting.xml, 解决方案如下:将maven的安装目录\conf目录下的setting.xml拷贝到C:\Users\lenevo\.m2目录下即可。 第二种错误: This a…

关于部署osd过程中:Device is in use by a device-mapper mapping问题解决
ceph环境:12.2.1 使用古老的ceph-disk工具部署osd,仅仅prepare过程中就出现如上所示问题 Device is in use by a device-mapper mapping md127 解决方法如下: 由于device-mapper为系统自己的磁盘映射器,此时检查系统是否有逻辑卷 pvs lvs vg…

spyder一打开就卡了_欧姆龙plc 用 SD 卡上传/下载程序
以Nx102为例,NJ类似。使用 SD 卡将 Sysmac Studio 编写的程序传入 NX1P2 内; 使用 SD 卡对NX1P2 的程序进行备份, 查看备份的程序, 并把备份的程序传入另一台对应型号的 NX1P2 内。一、 使用 SD 卡将 Sysmac Studio 写的程序传入 …

Unity3D 中 2D_Toolkit插件下载 和 导入方法
Unity3D 中 2D_Toolkit插件下载 和 导入方法 1.你把下载来的包放到 安装目录:Editor\Standard Packages里面。 2.然后按ctrl9,进入asset store,等页面加载。 3.页面加载成功后,如果有账号,就登录,没有账号先…

Emacs 使用YASnippet
<?xml version"1.0" encoding"utf-8"?> Emacs 使用YASnippetUP | HOME Emacs 使用YASnippet Table of Contents 1 安装YASnippent2 安装 org-mode字典3 org-mode中使用教程4 YASnippet增加模板1 安装YASnippent $ cd ~/.emacs.d/plugins $ git c…

ruoyi后台管理系统分析(三)---admin包
三、admin包 --web包 -----controller包 -----------common包 CommonController.java------通用请求处理 package com.ruoyi.web.controller.common;import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest;…

ceph-objectstore-tool工具使用详解
文章目录简介使用OSD相关操作PG相关操作对象相关操作总结简介 ceph-objectstore-tool工具,能够操作到ceph最底层的数据,包括pg,对象层级。它能够对底层pg以及对象相关数据进行获取、修改。并能够对一些问题pg和对象进行简单修复。所以使用该工具进行操作…

slf4j导入那个依赖_学习SPRINGBOOT结合日志门面SLF4J和日志实现LOGBACK的混合使用
一、此处主要介绍在springboot工程下如何使用 logback slf4j 进行日志记录。logback主要包含三个组成部分:Loggers(日志记录器)、Appenders(输出目的在)、Layouts(日志输出格式) slf4j :如jdbc一样,定义了一套接口,是一个日志门面…

linux下发布的执行文件崩溃的问题定位 心得一则
C Release版本发布到客户处执行时,如果程序崩溃,有什么办法能够快速的确认程序的问题呢? 如果能gdb调试的话,比较简单了,可以使用gdb命令,类似如下:gdb ##set args ****b mainr#eipx/10i 0xb736…

7 个漂亮的 JavaScript 的时间轴组件 [转]
时间轴:通过互联网技术,依据时间顺序,把一方面或多方面的 时间足迹事件串联起来,形成相对完整的记录体系,再运用图文的形式呈现给用户;时间轴可以运用于不同领域,最大的作用就是把过去的事物系统…

Python 学习笔记: 反射
Python 反射应用 例子1: class Person:def __init__(self, name, age):self.name nameself.age agedef show(self):print(%s \s age is %s%(self.name, self.age))alex Person(alex, 18) # alex.show() if hasattr(alex, show):getattr(alex, show)() 转载于:ht…

C++多线程:互斥变量 std::mutex
文章目录描述成员函数总结描述 头文件 <mutex>使用 std::mutex <variable>简介 mutex是一种多线程变成中的同步原语,它能够让共享数据不被多个线程同时访问,它不支持递归得对互斥对象上锁特点 用方线程从它成功调用 lock 或 try_lock 开始&…

vim替换字符串带斜杠_Vim、gvim操作替换
~ 回复 以下关键词 查看更多IC设计教程 ~目前支持的关键词有:Innovus ICC or IC CompilerDC or Design Compiler PT or PrimeTimeUser Guide or UG LedaVCS Formality工艺节点 …

SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...
转:http://blog.csdn.net/miragesky2049/article/details/7204882 SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题 1、实现效果如下: 点击各个节点进入相应的链接 2、测试…

智能医疗?轻松实现!
每个中国人都及其关注养老和住房问题,在中国每个人都十分有存钱的意识。就目前来看,现在的医疗和住房保障还没有能够满足我们现在的需求,因而,存钱显得尤为重要。我们关注医疗,是因为每个人都会面临年老,每…

TokuDB vs Innodb 基准测试对比
随着业务的发展以及mysql存储数据量的越来越大,很多超大表不仅仅存储变的不易,维护也变得越来越困难,特别是频繁的ddl操作让运维变得痛苦不堪。当然表拆分可以解决类似的问题,但是对一个稳定的系统来说,表拆分对业务的…

C++ 多线程:互斥对象 lock_gurad
描述 头文件:<mutex>声明方式: template< class Mutex > class lock_guard;简介 lock_guard是一种互斥包装器,它提供了非常便捷的raii资源管控技术用来在对象生存周期内提供互斥锁。 lock_gurad很好得解决了互斥变量mutex的锁成员在函数异常期间无法正…

太TM难看了,我自己都看不下去了
继续研究文件IO。 作用是用System.in输入一个文件路径,然后打印文件里的所有行。 而且虽然没仔细检查过,哦不就是因为没检查过,所以肯定不够健壮。 1 import java.io.*;2 import java.util.Scanner;3 4 public class test {5 public stat…

儿童吹泡泡水简单配方_自制泡泡水最简单配方的做法教程
泡泡吸引着各个年龄段的人,就像是反射彩虹的表面,在微风中漂浮。无论您是出于什么原因,都很容易在其中找到快乐。吹泡泡可以让小孩玩上几个小时,而大一点的孩子可以尝试制作最佳泡泡液。对于年轻的萌芽科学家来说,制备…

Linux系统下统计目录及其子目录文件个数
改变脚本权限:(这里假设你的脚本叫FileCount.sh) chmod ax FileCount.sh 脚本: 1 #!/bin/sh 2 echo 查看某目录下文件的个数 3 ls -l |grep "^-"|wc -l 4 5 echo 查看某目录下文件的个数,包括子目录里的。 6 ls -lR|grep "^-…

【Rsync项目实战一】备份全网服务器数据
目录 【Rsync项目实战】备份全网服务器数据 【企业案例】1.1 环境部署1.2 开始部署backup服务器:Rsync服务端过程:1.3 开始部署nfs01服务器:Rsync客户端过程:【Rsync项目实战】备份全网服务器数据 标签(空格分隔&#…

C++ 多线程:条件变量 std::condition_variable
文章目录描述使用描述 头文件<condition_variable> 定义 class condition_variable; 简介 之前我们也已经介绍过了C多线程中互斥变量存在,已经足够支持多线程中对共享普通系统数据的合理访问。但是因为多线程中同一时刻必然会有一个线程持有锁,一…

小晶粒zsm分子筛合成表征实验报告_Nat. Mater.:区域选择性合成亚纳米金属-分子筛材料...
本文来自微信公众号:X-MOLNews亚纳米尺度的负载型催化剂是近些年多相催化领域以及相关材料科学领域的热门方向。围绕着单原子催化剂、团簇催化剂的论文如井喷一般出现在各大期刊上。关于亚纳米尺度金属催化剂的制备方法、表征方法、催化性能或是相关的理论研究都在如…

【翻译】使用新的Sencha Cmd 4命令app watch
原文:http://www.sencha.com/blog/using-the-new-app-watch-command-in-sencha-cmd-4/作者:Don Griffin Don Griffin is a member of the Ext JS core team. He was an Ext JS user for 2 years before joining Sencha and has over 20 years of softwar…

《设计模式解析(第2版)》
2019独角兽企业重金招聘Python工程师标准>>> 1. 软件开过程中的视角 视角 描述 概念 “软件要负责什么?” 规约 “怎么使用软件?” 实现 ”软件怎样履行自己的责任?“ 可能使用的另外一组视角:使用视角和创建/…

Nmap帮助文档解释
目标指定(target specifiction) 1、用法:Nmap[扫描类型][设置]{设备列表} 注:[]{} -> 中的内容必须有 <> -> 中的内容可以有可以没有 2、地址类型:主机名、ip地址、网段 3、-iL<文件名> 通过文件输入地址 4、-i…

C++ 多线程:future 异步访问类(线程之间安全便捷的数据共享)
文章目录future前言future描述future类成员使用总结future前言 首先查看如下代码 #include <iostream> #include <thread> #include <future> #include <mutex>using namespace std;void fun1(int n,int &x) {int res 1;for (int i n; i>1;…

bldc不同载波频率_广播百科 频率调制
∧ 请关注为星标,在知识的海洋每天进步1%第 463期频率调制,简称“调频”,它是一种使载波的瞬时频率随调制信号的变化规律而变化的调制方法。实现这种调制方法的电路称调频器,广泛用于调频广播、电视伴音、微波通信、锁相电路和扫频仪等方面。…