【深入理解C++】拷贝构造函数

article/2024/9/17 4:07:53

文章目录

  • 1.拷贝构造函数
  • 2.默认的拷贝操作
  • 3.默认拷贝构造函数
  • 4.何时调用拷贝构造函数

1.拷贝构造函数

拷贝构造函数是构造函数的一种。当利用已存在的对象创建一个新对象时,就会调用新对象的拷贝构造函数进行初始化。

拷贝构造函数的格式是固定的,即接收一个const引用作为参数。

拷贝构造函数一般不要声明成 explicit。

如果自己定义了拷贝构造函数,那么系统默认的拷贝操作就不存在了,此时必须指定拷贝方式,即必须在自己的拷贝构造函数中手动给类成员赋值,以免出现类成员没有被赋值就被使用的情况。

#include <iostream>
using namespace std;class Car
{
public:int m_price;int m_length;Car(int price = 0, int length = 0) : m_price(price), m_length(length){cout << "调用了Car的构造函数" << endl;}Car(const Car& car) : m_price(car.m_price), m_length(car.m_length){cout << "调用了Car的拷贝构造函数" << endl;}void display(){cout << "price = " << m_price << ", length = " << m_length << endl;}
};int main()
{Car car1(100, 5);Car car2(car1);car2.display();return 0;
}

输出结果如下:

在这里插入图片描述

汇编代码如下:

在这里插入图片描述

2.默认的拷贝操作

默认情况下,类对象的拷贝是每个成员变量逐个拷贝。

在下面代码中,我们没有为 Car 类定义拷贝构造函数,从图中可以看出,编译器并没有为 Car 类生成一个默认拷贝构造函数,而是直接给每个成员变量逐个拷贝赋值。

#include <iostream>
using namespace std;class Car
{
public:int m_price;int m_length;Car(int price = 0, int length = 0) : m_price(price), m_length(length){cout << "调用了Car的构造函数" << endl;}void display(){cout << "price = " << m_price << ", length = " << m_length << endl;}
};int main()
{Car car1(100, 5);Car car2(car1);car2.display();return 0;
}

输出结果如下:

在这里插入图片描述

汇编代码如下:

在这里插入图片描述

3.默认拷贝构造函数

与 默认构造函数 类似,只有在某些特定的情况下,编译器才会给类自动生成一个默认拷贝构造函数。

在下面代码中,我们没有为 Person 类定义拷贝构造函数,但 Person 类中包含了一个 Car 类对象且这个 Car 类对象有拷贝构造函数,此时编译器会为 Person 类自动生成一个默认拷贝构造函数。

#include <iostream>
using namespace std;class Car
{
public:int m_price;Car(int price = 0) : m_price(price){cout << "调用了Car的构造函数" << endl;}Car(const Car& car) : m_price(car.m_price){cout << "调用了Car的拷贝构造函数" << endl;}void display(){cout << "price = " << m_price << endl;}
};class Person
{
public:int m_age;Car car;
};int main()
{Person person1;Person person2(person1);return 0;
}

输出结果如下:

在这里插入图片描述

汇编代码如下:

在这里插入图片描述

在下面代码中,Person 类中包含了一个 Car 类对象且这个 Car 类对象有拷贝构造函数,我们手动为 Person 类定义拷贝构造函数,此时就会调用我们自定义的拷贝构造函数。

#include <iostream>
using namespace std;class Car
{
public:int m_price;Car(int price = 0) : m_price(price){cout << "调用了Car的构造函数" << endl;}Car(const Car& car) : m_price(car.m_price){cout << "调用了Car的拷贝构造函数" << endl;}void display(){cout << "price = " << m_price << endl;}
};class Person
{
public:int m_age;Car car;Person(int age = 0, int price = 0) : m_age(age), car(price){cout << "调用了Person的构造函数" << endl;}Person(const Person& person) : m_age(person.m_age), car(person.car){cout << "调用了Person的拷贝构造函数" << endl;}
};int main()
{Person person1;Person person2(person1);return 0;
}

输出结果如下:

在这里插入图片描述

汇编代码如下:

在这里插入图片描述

4.何时调用拷贝构造函数

拷贝构造函数和拷贝赋值运算符的行为比较相似,都是将一个对象的值复制给另一个对象,但是其结果却有些不同,拷贝构造函数使用传入对象的值生成一个新的对象的实例,而拷贝赋值运算符是将对象的值复制给一个已经存在的实例。这种区别从两者的名字也可以很轻易地分辨出来,拷贝构造函数也是一种构造函数,那么它的功能就是创建一个新的对象实例;拷贝赋值运算符是执行某种运算,将一个对象的值复制给另一个对象(已经存在的)。

调用的是拷贝构造函数还是拷贝赋值运算符,主要是看是否有新的对象实例产生。如果产生了新的对象实例,那调用的就是拷贝构造函数;如果没有,那就是对已有的对象赋值,调用的是拷贝赋值运算符。

调用拷贝构造函数主要有以下场景:

  • 使用一个对象给另一个对象初始化
  • 对象作为函数的参数,以值传递的方式传给函数
  • 对象作为函数的返回值,以值的方式从函数返回
#include <iostream>
using namespace std;class Student
{
private:int age;public:Student(){age = 0;cout << "调用了无参的构造函数 - " << this << endl;}Student(int v){age = v;cout << "调用了带参的构造函数 - " << this << endl;}Student(const Student& stu) // 拷贝构造函数{age = stu.age;cout << "调用了拷贝构造函数 - " << this << endl;}Student& operator=(const Student& stu) // 拷贝赋值运算符{age = stu.age;cout << "调用了拷贝赋值运算符 - " << this << endl;return *this;}~Student(){cout << "调用了析构函数 - " << this << endl;}void display(){cout << "调用了display函数 - " << this << endl;}
};void fun1(Student stu)
{return;
}Student fun2()
{Student stu;return stu;
}int main()
{Student stu1(18);cout << "------------------------------" << endl;Student stu2(stu1);cout << "------------------------------" << endl;Student stu3 = stu1;cout << "------------------------------" << endl;Student stu4;stu4 = stu1;cout << "------------------------------" << endl;fun1(stu1);cout << "------------------------------" << endl;fun2();cout << "------------------------------" << endl;stu4 = fun2();cout << "------------------------------" << endl;Student stu5 = fun2();cout << "------------------------------" << endl;return 0;
}

输出结果如下:

在这里插入图片描述


http://chatgpt.dhexx.cn/article/tqr5Js2o.shtml

相关文章

C++拷贝构造函数详解

一. 什么是拷贝构造函数 首先对于普通类型的对象来说&#xff0c;它们之间的复制是很简单的&#xff0c;例如&#xff1a; int a 100; int b a; 而类对象与普通对象不同&#xff0c;类对象内部结构一般较为复杂&#xff0c;存在各种成员变量。 下面看一个类对象拷贝的简…

c++拷贝构造函数(深拷贝,浅拷贝)详解

一、什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。 下面看一个类对象拷贝的简单例子。 #include<iostream> using n…

YOLO 裂缝检测

环境 python3.5 yolov3 opencv keras

基于OpenCV的混凝土裂纹检测

基于OpenCV的混凝土裂纹检测 前言 这是我发的第一次博客&#xff0c;有什么建议大家可以给我留言&#xff0c;感激不尽! 接下来&#xff0c;我们进入正题。 一、使用函数库 numpy, opencv, heapq, skimage.morphology 二、使用步骤 1.初步预处理 初步预处理包括&#xf…

【图像识别】基于计算机视觉实现路面裂缝检测识别系统matlab代码

1 简介 随着公路与铁路事业的飞速发展,各类车辆和里程的增加,铁路的一次次提速,都对路面产生了巨大的压力。不论是公路路面还是铁路路面,路面裂纹都能随处可见,由路面裂纹造成的交通事故时有发生。研究路面裂纹检测方法对于路面维护、交通安全具有极其重大意义。近年来,路面裂…

基于计算机视觉的裂纹检测方案

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达01. 数据集 我们首先需要从互联网上获取包含墙壁裂缝的图像&#xff08;URL格式&#xff09;数据。总共包含1428张图像&#xff1a;其中一半是新的且未损坏的墙壁&#x…

halcon裂纹缺陷检测

针对这一类表面的检测就不能单纯依靠帧差或者背景差来完成&#xff0c;因为背景的纹理不可能和当前图像的纹理完全相同。 方法一—局部阈值分割 一、局部阈值分割 1、gen_sin_bandpass–局部阈值分割 dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset,…

使用 Python 进行深度学习以进行裂纹检测

使用 Python 进行深度学习以进行裂纹检测 问题陈述数据集准备训练模型结论参考 问题陈述 虽然新技术已经改变了我们生活的方方面面&#xff0c;在建筑领域似乎牛逼正在努力追赶。目前&#xff0c;建筑物的结构状况仍然主要是人工检查。简单来说&#xff0c;即使现在需要检查结…

Halcon-表面检测-----裂纹检测

对应示例程序&#xff1a; detect_mura_defects_blur.hdev 目标&#xff1a;实例实现LCD上有很多污点干扰下&#xff0c;检测LCD的印痕检测。 思路为&#xff1a;对LCD图像进行拆分&#xff0c;提取RGB三个分量。 对B分量进行处理&#xff0c;将其转换为频域内图像&#xff0…

图像中的裂纹检测

01. 数据集 我们首先需要从互联网上获取包含墙壁裂缝的图像(URL格式)数据。总共包含1428张图像:其中一半是新的且未损坏的墙壁;其余部分显示了各种尺寸和类型的裂缝。 第一步:读取图像,并调整大小。 images = []for url in tqdm.tqdm(df[content]): response = req…

html图片与文字轮播,我是这样写文字轮播的

原标题&#xff1a;我是这样写文字轮播的 作者&#xff1a;一半水一半冰 原文&#xff1a;http://www.cnblogs.com/jingh/p/6377736.html 1写在前面 最近总结下之前的工作&#xff0c;才恍然发现时间的流逝永远是悄无声息的&#xff0c;离开学校那座象牙塔已经也有大半年的时间…

IOS 文本文字下面添加下划线

2019独角兽企业重金招聘Python工程师标准>>> UILabel *infolabel [[UILabel alloc] initWithFrame:CGRectMake(30*RATIO,260*RATIO, self.view.bounds.size.width-60*RATIO, 20*RATIO)];infolabel.text "infoimcba.com";infolabel.textColor [UIColor …

html语言 特效字,用HTML和CSS实现酷炫的文字特效

前言 马上我们就要进入下一个阶段&#xff0c;也就是HTML和CSS实现前端界面的阶段了&#xff0c;想必很多小伙伴都想给自己的页面加点酷炫的特效&#xff0c;今天&#xff0c;我就给大家整理了一些非常酷炫的文字特效来装点你的页面&#xff01;有些是从网络上找的&#xff0c;…

python抓取图片数字_python 实现识别图片上的数字

Python 3.6 版本 Pytesseract 图像验证码识别 环境: (1) win7 64位 (2) Idea (3) python 3.6 (4) pip install pillow <&nbsp>pip install pytesseract (5) 识别引擎tesseract-ocr 安装 安装tesseract-ocr的识别引擎 第一步:下载安装包 我下载的是64位,根据自…

html改变字母间距,css怎么调整字体间距?

在前端开发的过程中&#xff0c;有时候可能会出现字与字之间比较紧凑&#xff0c;我们可以通过css设置文字间隔让字与字之间的距离大一点&#xff0c;下面我们来看一下如何使用css调整字体间距。 css中解决字与字间隔的方法是使用css样式属性letter-spacing&#xff0c;letter-…

html ul 加点,HTML ul compact 属性 | 菜鸟教程

HTML compact 属性 实例 在无序列表中使用compact属性&#xff1a; CoffeeTeaMilk 尝试一下 浏览器支持 所有主流浏览器都不支持 compact 属性。 定义和用法 HTML5 不支持 compact 属性。 请使用 CSS 替代。 的 compact 属性在 HTML 4.01 已废弃。 compact 属性是一个 boole…

css怎么将文字底下设置颜色,css如何设置文字颜色

css设置文字颜色的方法&#xff1a;1、在DIV标签内使用color颜色样式&#xff0c;代码为【 www.php.cn 】&#xff1b;2、在CSS选择器中使用color颜色样式CSS代码。 本教程操作环境&#xff1a;windows7系统、css3版&#xff0c;DELL G3电脑。 css设置文字颜色的方法&#xff1…

markdown/LaTeX中在字母下方输入圆点的方法

看下面的关联代数的乘法定义, 如果需要在 z z z下面加上一个点, 应该怎么做呢? 下面是一个采用\stackrel命令的方法 {\huge{}_{\stackrel{{}_{{}_{{}_{{}_z}}}}{{}^\cdot}}}\!\leq y⋅ z ⁣ ≤ y {\huge{}_{\stackrel{{}_{{}_{{}_{{}_z}}}}{{}^\cdot}}}\!\leq y ⋅z​​​​​…

html 字前边自动加点,css实现文字越界加点点点显示,并且后面紧跟一个图标

文字越界添加...显比抖朋要插支一圈不者地示 在HTML页面上&#xff0c;会遇到当文字长度超出一定长度的时候&#xff0c;将超出的部分显示为...的情况&#xff0c;这个功能很好实现&#xff0c;很多人都可以直接写出来。 示例代码&#xff1a; .demo { display: block; text-ov…

css文字下方加点

1、border-bottom: 1px dashed #333; 2、 text-emphasis: dot; text-emphasis-position: under; -webkit-text-emphasis: dot; -webkit-text-emphasis-position: under;