C++知识点:拷贝构造函数例子
//拷贝构造函数:
//函数参数传递时调用一次拷贝构造函数,给对象赋值时调用一次拷贝构造函数,对象作为参数传递后会被及时销毁。
#include <fstream>
#include <string>
using namespace std;
ofstream out("HowMany2.out"); class HowMany2
{
string name;//object identifier
static int objectCount;
public:
HowMany2(const string& id = "") : name(id)
{
++objectCount;
print("HowMany2()");
}
~HowMany2()
{
--objectCount;
print("~HowMany2()");
}
// the copy-constructor;
HowMany2(const HowMany2& h) : name(h.name)
{
name += " copy";
++objectCount;
print("HowMany2(const HowMany2&)");
}
void print(const string& msg = "") const
{
if (msg.size() != )
{
out << msg << endl;
}
out << '\t' << name << ":" << "objectcount=" << objectCount << endl;
}
}; int HowMany2::objectCount = ;
//pass and return By value:
HowMany2 f(HowMany2 x)
{
x.print("x argument inside f()");
out << "Returning from f()" << endl;
return x;
} int main()
{
HowMany2 h("h");
//1.HowMany2()
//2.h:objectCount = 1
out << "Entering f()" << endl;
//3.Entering f()
/*进入f(h)
此时拷贝构造函数被编译器调用,完成传值过程,
在f()内创建了一个新对象,他是h的拷贝,所以对象变成2
输出:
//传递对象作为函数参数时即发生拷贝构造
4.HowMany2(const HowMany2&)
5.h copy :objectcount=2
6.x argument inside f()
7.h copy:objectcount=3
8.returning from f()
第8显示了从f()返回的开始情况,但在局部变量“h拷贝”销毁前
(在函数结尾这个局部变量出了范围)他必须被拷入返回值,也就是h2.
以前未创建的对象h2是从现在的对象(在函数f()内的局部变量创建的)
所以在第9行拷贝构造函数又被调用了。
现在对于h2的标识符,名字变成了h拷贝的拷贝,因为他是从拷贝拷过来的,
这个拷贝是函数f()内部对象,
在对象返回之后,函数结束之前,对象数暂时变为3,但是此后h拷贝被销毁。 */
HowMany2 h2 = f(h);
//在完成对f()的调用后,仅有两个对象h和h2,这是看到h2最终是h拷贝的拷贝
h2.print("h2 after call to f()");
out << "call f() , no return value" << endl;
//从第15行开始调用f(h),这次调用忽略了返回值,在16行可以看到恰好在参数传入之前,
//拷贝构造函数被调用。和前面一样,21行显示了为了返回值而调用拷贝构造函数。但是拷贝构造函数必修
//有一个作为它的目的地址(this指针)的工作地址,但这个地址从哪里来呢?
//每当编译器为了正确地计算一个看不见的对象而需要一个临时对象时,编译器都会创建一个,在这种情况下
//编译器创建一个看不见的对象作为函数f()忽略了的返回值的目标地址。这个临时对象的生存期应该尽可能的短暂,
//这样空间就不会被这些等待被销毁的而且占用资源的临时对象搞乱。在一些情况下,临时对象可能立刻被传递给
//另外的函数,但是现在这种情况下临时对象不再需要,所以一旦调用完毕就对内部对象调用析构函数(23-24)
//这个临时对象被销毁(25-26)
//28-31行,h2,h被销毁
f(h);
out << "After call to f()" << endl;
}
//输出结果:
/*
1.HowMany2()
2.h:objectCount=1
3.Entering f()
//传递对象作为函数参数时即发生拷贝构造
4.HowMany2(const HowMany2&)
5.h copy :objectcount=2
--------------------------
6.x argument inside f()
7.h copy:objectcount=3
8.returning from f()
//返回对象再次调用拷贝构造函数
--------------------------
9.HowMany2(const HowMany2&)
10.h copy copy: objectCount=3
//临时对象使用完毕,析构
11.~HowMany2()
12.h copy : objectcount=2
13.h2 after call to f()
14.h copy copy: objectCount=2
15.call f(),no return value
//f(h)
16.HowMany2(const HowMany2&)
17.h copy: objectcount=3
18.x argument inside f()
19.h copy:objectCount=3
20.Returning from f()
//f(h)后赋值给未知的值,在此调用拷贝构造函数
21.HowMany2(const HowMany2&)
22.h copy copy:objectCount = 4
//临时对象使用完毕再次调用析构函数
23.~HowMany2()
24.h copy : objectCount = 3
//销毁匿名的对象
25.~HowMany2()
26.h copy copy:objectCount=2
27.After call to f()
28.~HowMany2()
29.h copy copy :objectcount=1
30.~HowMany2()
31.h: objectcount=0
*/
C++知识点:拷贝构造函数例子的更多相关文章
- C++ 一个例子彻底搞清楚拷贝构造函数和赋值运算符重载的区别
class TestChild { public: TestChild() { x=; y=; printf("TestChild: Constructor be called!\n&quo ...
- 从一个例子讲解拷贝构造函数与return
#include "iostream" using namespace std; class Location { public: Location(, ) { X = xx; Y ...
- C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?
之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝.然而今天看到一篇文章发现自己对拷贝构造的参数理解有误. 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导 ...
- PoEdu - C++阶段班【Po学校】- Lesson03-4_构造函数&赋值函数&拷贝构造函数&学习方式 - 第6天
PoEdu - C++阶段班[Po学校]- 第6天 课堂选择题目: 1 关于转换构造函数 ClassDemo demo = 1; 调用转换构造函数 2 关于拷贝赋值函数 demo =2; 首 ...
- C++拷贝构造函数(深拷贝,浅拷贝)
对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. #i ...
- 【转】C++的拷贝构造函数深度解读,值得一看
建议看原帖 地址:http://blog.csdn.net/lwbeyond/article/details/6202256 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很 ...
- C++拷贝构造函数(深拷贝,浅拷贝)
http://www.cnblogs.com/BlueTzar/articles/1223313.html 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; ...
- C++拷贝构造函数详解(转载)
一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a = 100; int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员 ...
- 【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解
c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3 ...
随机推荐
- maven如果正常配置不成功,就按照我的就可以配置成功了
常规的配置如下 非常规的配置 如果上面都没有问题,还是不能创建成功,就是maven配路径的问题,如图所示 如下图所示即是正确配置
- tensorflow:验证码的识别(下)
上两篇详细的说明了验证码的识别,不过我们采用的是方法二,下面采用方法一.注意和方法二的区别. 验证码识别方法一: 把标签转为向量,向量长度为40.(4位数字验证码) 验证码的生成和tf.record的 ...
- jQuery分步步骤
插件描述:jQuery上一步.下一步,分步步骤,兼容性如下: 使用方法 1.引入样式和脚本 <link rel="stylesheet" type="text/cs ...
- zookeeper 学习 状态机复制的共识算法
https://www.youtube.com/watch?v=BhosKsE8up8 state machine replication 的 共识(consensus) 算法 根据CAP理论,一个分 ...
- nginx 服务脚本编写模板
编写nginx服务脚本:脚本内容如下: [root@www ~]# cat /etc/init.d/nginx #!/bin/bash # nginx Startup script for the N ...
- Apache ActiveMQ 远程代码执行漏洞 (CVE-2016-3088)案例分析
部署ActiveMQ运行环境 在linux上部署apache-activemq-5.10.0-bin.tar.gz 通过tar -zxvf apache-activemq-5.10.0-bin.ta ...
- ThinkPHP页面跳转success与error方法
首先是控制器中,可以使用下代码: config配置如下: 'TMPL_ACTION_ERROR' => 'Public:error', // 默认错误跳转对应的模板文件 'TMPL_ACTION ...
- 修改注册表.exe的文件目录
文件打开方式不能选择默认打开文件 cmd >regedit 以sublime_text为例 HKEY_CLASSES_ROOT/Applications/sublime_text.exe/she ...
- react-route4 学习记录
新建项目 create-react-app react20180413 安装路由 npm install react-router-dom -S 跑通路由 删除全部文件后 重新新建index.js 代 ...
- Pushing Boxes POJ - 1475 (嵌套bfs)
Imagine you are standing inside a two-dimensional maze composed of square cells which may or may not ...