C++ Copy Constructor (拷贝构造函数,复制构造函数)
1.什么是Copy Constructor?
Copy Constructor 是一个特殊的构造函数,一般只有一个参数,这个参数一般是用const修饰的,对自己类的一个引用(reference)。什么时候会用到Copy Constructor?
当我们定义一个对象时,它是由另外一个对象来初始化的时候就用到Copy Constructor了。还有就是在一个方法以值作为参数传进去或者一个方法中以值作为返回。
对于我这新手C++,Copy Constructor 用的比较少,真正用到了也不知道,因为一个类缺少 Copy Constructor 时,编译器会自动生成一个。
2.赶快来看一个Copy Constructor例子
2.1系统默认会提供一个Copy Constructor
class People{
private:int m_age;
public:People(int age):m_age(age){cout << "constructor" << endl;}~People(){cout << "destructor" << endl;}int getAge() const{return m_age;}
};
一个简单的类,叫People,只有一个属性age
People p1(18);cout << "p1's age " << p1.getAge() << endl;People p2(p1);cout << "p2's age " << p2.getAge() << endl;
当我们调用上面的代码时的输出结果就是:
代码工作非常符合我们预期,因为系统会提供一个Copy Constructor,对类里的属性进行简单的赋值工作。
2.2自定义的Copy Constructor
class People{
private:int m_age;
public:People(int age):m_age(age){cout << "constructor" << endl;}//copy constructorPeople(const People& p){cout << "copy constructor" << endl;}~People(){cout << "destructor" << endl;}int getAge() const{return m_age;}
};
People p1(18);cout << "p1's age " << p1.getAge() << endl;People p2(p1);cout << "p2's age " << p2.getAge() << endl;
这次我们自定义了一个Copy Constructor
还是调用上次的代码,结果:
看,成功的调用了我们的copy constructor,因为我们的copy constructor 里什么也没做,所以p2的age就是一个未初始化的int值了。
2.3还有两种情况会触发调用Copy constructor
//作为一个值从函数中返回
People getPeople(){People p1(20);return p1;//会调用 copy constructor
}
//以值作为参数传入
void setPeople(People p1){//以值传入会调用 copy constructor//do nothing
}void setPeople(People& p1){//以引用传入不会调用 copy constructor//do nothing
}
因为调用copy constructor的消耗比较大,所以一般都以引用方式作为函数参数。
3. copy constructor 与 assignment operator 的区别
我们忘记提到的是下面这种写法也会触发copy constructor:
People p1(18);cout << "p1's age " << p1.getAge() << endl;People p2 = p1;cout << "p2's age " << p2.getAge() << endl;
这种写法似乎跟赋值很像。
我们修改People的类,增加重载=操作符。
class People{
private:int m_age;
public:People(int age):m_age(age){cout << "constructor" << endl;}People(const People& p){cout << "copy constructor" << endl;}People& operator=(const People& p1){cout << "assignment operator" << endl;m_age = p1.getAge();return *this;}~People(){cout << "destructor" << endl;}int getAge() const{return m_age;}
};
//测试代码
People p1(18);cout << "p1's age " << p1.getAge() << endl;People p2 = p1;cout << "p2's age " << p2.getAge() << endl;p2 = p1;
cout << p2.getAge() << endl;
通过上面的输出结果我们发现:
= 什么时候会调用Copy Constructor呢?在初始化的时候,也就是第一个 People p2 = p1。因为Copy Constructor 是一种 Constructor,也是负责初始化的。
什么时候=是赋值呢?两个都已经初始化,再调用=就是赋值了。
4. 浅拷贝和深拷贝
我们上面的类People只有一个简单的属性age,还是int类型的,进行简单的赋值就是浅拷贝,但是People类将来会变的复杂起来,后面可能会增加指针类型的属性。那么就会涉及到深拷贝了。
我的理解就是:浅拷贝:两个变量进行浅拷贝时,它们指向同一个地址,它们的值相同。这样会有问题,当其中的一个析构了那个地址,另外一个也没有了,有时候会发生错误,但浅拷贝比较廉价。
深拷贝:两个变量进行深拷贝时,第二变量会重新申请一块区域来存放跟第一个变量指向地址的值。两个东西完全是独立的,只是值相同。消耗比较大,因为要重新申请空间。
关于Copy Constructor,就先这样吧。
5.禁用Copy Constructor
把Copy Constructor设置为private就行了。以我的水平,我还不知道什么情况要这样做 =。=
C++ Copy Constructor (拷贝构造函数,复制构造函数)
C++ Copy Constructor (拷贝构造函数,复制构造函数)相关推荐
- C++ 构造函数、复制构造函数,拷贝构造函数(深拷贝、浅拷贝)
文章目录 前言 一.什么是构造函数? 二.构造函数的分类 复制构造函数 复制构造函数被调用的三种情况 复制构造函数在以下三种情况下会被调用. 三.拷贝构造函数的分类 深.浅拷贝构造函数的区别 示例代码 ...
- 编译器角度看C++复制构造函数
[C++对象模型]复制构造函数的建构操作 关于复制构造函数的简单介绍,可以看我以前写过的一篇文章C++复制控制之复制构造函数该文章中介绍了复制构造函数的定义.调用时机.也对编译器合成的复制构造函数行为 ...
- [C++]有关深复制与copy constructor的一些问题与实例
纸上得来终觉浅,绝知此事要躬行 --- 今天对此话有了实际的领悟.之前学习C++的时候,自以为已经把深复制和复制构造函数等这些知识已经掌握了,但真正写起项目来的时候,还是不能提前考虑这些问题,直到问题 ...
- C++ 复制控制之复制构造函数
7月26日更新: 过了这么长的时间回过头来看,发现文章中有几个点说错(用红字标出): 构造函数不是只有唯一一个参数,它也可以是多参数形式,其第二参数及后继以一个默认值供应. 不是没有声明复制控制函数时 ...
- frontcon函数用不了_C++复制构造函数与析构函数
想用机器人赋能未来,少不了扎实的编程的基本功,让我们跟着清华大学的C++语言程序设计课程一起过一遍C++的语法知识吧! 当定义基本类型的变量时,经常会用已有的变量去初始化新定义的变量,当定义对象的时候 ...
- ❥关于C++之类的复制构造函数赋值运算符
C++自动提供了下面这些成员函数: 默认构造函数,如果没有定义构造函数 默认析构函数,如果没有定义 复制构造函数,如果没有定义 赋值运算符,如果没有定义 地址运算符,如果没有定义 一.复制构造函数 复 ...
- 复制构造函数(拷贝构造函数)
也许很多C++的初学者都知道什么是构造函数,但是对复制构造函数(copy constructor)却还很陌生.对于我来说,在写代码的时候能用得上复制构造函数的机会并不多,不过这并不说明复制构造函数没什 ...
- C++拷贝构造函数(复制构造函数)详解
link 复制构造函数是构造函数的一种,也称拷贝构造函数,它只有一个参数,参数类型是本类的引用. 如果类的设计者不写复制构造函数,编译器就会自动生成复制构造函数.大多数情况下,其作用是实现从源对象到目 ...
- 为什么禁用拷贝(复制)构造函数
关于C++的拷贝构造函数,很多的建议是直接禁用.为什么大家会这么建议呢?没有拷贝构 造函数会有什么限制呢?如何禁用拷贝构造呢?这篇文章对这些问题做一个简单的总结. 这里讨论的问题以拷贝构造函数为例子, ...
最新文章
- androidsettitle方法_Android使用setCustomTitle()方法自定义对话框标题
- JVM,JDK,JRE和OpenJDK有什么区别?
- python练手小游戏_Python小游戏练手EMS员工项目自学者练习
- Autodesk Cloud Accelerator Program 开始报名
- 安装oracle11g时,Enterprise Manager配置成功,出现以下警告……
- 中国银屑病患者中银屑病关节炎的患病率和特征
- 浙大远程教育计算机作业3,2016浙大远程教育计算机应用基础作业-3剖析
- 我爱计算机视觉精华文章分类汇总(2018年12月13日)
- SpringBoot + Dubbo + Zookeeper搭建一个简单的分布式服务
- Windows Terminal 已上架,快尝鲜
- 转:C++中STL用法总结
- andriod studio获取root_怎样获得root权限
- 易之风门诊收费系统 v1.0 官方
- 【Zeekr_Tech】TARA攻击树分析方法论
- Docker Swarm secrets
- 深入探讨 Room 2.4.0 的最新进展
- php发邮件附件,PHP使用PHPMailer发送邮件和附件的方法
- C#检索局域网内主机的IP、MAC地址
- 古代的电子计算机,古代也有黑科技:周朝的智能机器人,元朝的电子计算机!...
- 嵌入式linux学习笔记(一)