`
synchronized_lala
  • 浏览: 39825 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

对构造函数、拷贝构造函数和赋值操作符调用的简单回顾

阅读更多

本文只是测试构造函数、拷贝构造函数和赋值操作符的调用问题,不涉及这些函数内的具体实现,所以多包涵

还有如果觉得有不足之处还望指出,谢谢…………

 

 

#include<iostream>

using namespace std;

class Object{  
	
 	 char* name;
public:
	Object() 
	{
		cout << "Objected is constructed.(无参数)" << endl; 
	}

	Object(char* s) //
	{
		name = s;//
		cout << "Objected is constructed.(参数)" << endl; 
	}

	Object( const Object& o) 
	{
//为对象申请内存并进行出错检查;(本文没有处理)
//从对象o复制到本对象
		name = o.name;
		cout << "Object is copied." << endl; 
	}

	char* getName() 
	{ 
		return name;
	}
	Object & operator = (const Object& lala)
	{
		name = lala.name;
		cout << "Object is operator =." << endl; 

		return *this;
	}

	~Object()
	{ 
		cout << "Object is destructed." << endl;
	}


};

Object getObject( Object o)
{ 
	cout << "getO" << endl;//

	return o; 
}

Object getObject1( Object& o)
{ 
	cout << "getO1" << endl;//

	return o; 
}

Object& getObject2( Object& o)
{ 
	cout << "getO2" << endl;//

	return o; 
}


int main()
{

	Object o("zhangsan");

	Object o1;
	o1 = getObject( o);
	cout << endl;

	cout << "Object o2 = getObject(o):" << endl;
	Object o2 = getObject(o);//相当于Object o2(getObject(o));
	cout << endl;

	cout << "o1 = getObject(o):" << endl;
	o1 = getObject(o); 
	cout << endl << endl;

//getObject1
	cout << "getObject1:" << endl;
	Object o11;
	o11 = getObject1( o);
	cout << endl;

	cout << "Object o22 = getObject(o):" << endl;
	Object o22 = getObject1(o);
	cout << endl;

	cout << "o11 = getObject(o):" << endl;
	o11 = getObject(o);
	cout << endl << endl;

//getObject2
	cout << "getObject2:" << endl;
	Object o111;
	o111 = getObject2( o);
	cout << endl;

	cout << "Object o222 = getObject(o):" << endl;
	Object o222 = getObject2(o);
	cout << endl;

	cout << "o111 = getObject(o):" << endl;
	o111 = getObject(o);

	cout << "end" << endl;

	return 0;
}
 

 

 

Objected is constructed.(参数)

Objected is constructed.(无参数)

Object is copied.           //每次传参都会构建临时对象

getO

Object is copied.

Object is destructed.

Object is operator =.

Object is destructed.

 

Object o2 = getObject(o):

Object is copied.

getO

Object is copied.

Object is destructed.

 

o1 = getObject(o):

Object is copied.

getO

Object is copied.

Object is destructed.

Object is operator =.

Object is destructed.

 

 

getObject1:

Objected is constructed.(无参数)

getO1

Object is copied.

Object is operator =.

Object is destructed.

 

Object o22 = getObject(o):

getO1

Object is copied.

 

o11 = getObject(o):

Object is copied.

getO

Object is copied.

Object is destructed.

Object is operator =.

Object is destructed.

 

 

getObject2:

Objected is constructed.(无参数)

getO2

Object is operator =.

 

Object o222 = getObject(o):

getO2

Object is copied.

 

o111 = getObject(o):

Object is copied.

getO

Object is copied.

Object is destructed.

Object is operator =.

Object is destructed.

end


拷贝构造函数和赋值操作符:

同样是利用现有对象的值,生成/更新另一个对象的值。
区别在于:拷贝构造函数是去完成对未初始化的存储区的初始化,而赋值操作符则是处理一个已经存在的对象。对一个对象赋值,当它一次出现时,它将调用拷贝构造函数,以后每次出现,都调用赋值操作符。

定义对象a,并用另一个对象b对a进行初始化时,
若没有拷贝构造函数时,那么编译器会自动生成一个
T b(1);//假设对象b已经初始化
T a(b);//初始化阶段,调用拷贝构造函数
T c = b;//虽然使用了“=”,但是初始化阶段,仍调用拷贝构造函数
c = a; //因为对象c已经定义,所以此处调用赋值操作符重载函数。如果没有编译器会自动生成一个。 

 

1
1
分享到:
评论
2 楼 synchronized_lala 2012-11-21  
lazy_ 写道

好激动,有人回复了,而且那么详细。像你开始说的,我其实只能自己理解,觉得有点写不清楚。而且你比我理解的深刻,至于后面提到的copy constructor参数为什么是引用类型,我还么考虑到呢,嘻嘻……
你说的指针和引用类型的区别分享的网址我明天就去好好研究一下,你说学java比我学C++还……不过我这水平我也不好意思说自己学C++的了,呵呵
谢谢你的回复,
1 楼 lazy_ 2012-11-21  
我用1个小时实验了你的程序。感觉你的总结看起有点难受。。。
你是想说明以下的问题而已吧?博主看看我有没有理解错。工作我也写一小部分C++。。。JAVA、JS才是我的主行。

1.
Object o("zero");
Object o1;
o1 = o;


Object o("zero");
Object o1= o;


是不同的。

前者会调用operator=,而后者会调用copy conostructor。后者相当于调用constructor(object&)。为什么后者会调用copy constructor?后者o1只是变量名而已,几乎是没有什么意义的,遇到'=',从逻辑上只可能做个简单的引用操作或复制操作,是复制还是引用呢?C++提供了两种语法,Object& o1 = o;表示引用,而Object o1 = o1表示复制,相对地JAVA,比较简洁,只提供了引用的方式。而前者的o1是个对象,遇到'=',理所当然地会调用自身的operator=方法了。


其次就是一些基本的知识:

函数的形参是对象引用的话,那么调用该函数,准备参数时不会调用copy constructor;
函数的形参是对象的话,那么调用该函数,准备参数时会调用copy constructor;

函数的返回值是对象引用的话,那么函数返回时不会调用copy constructor;
函数的返回值是对象的话,那么函数返回是会调用copy constructor。


在学习博主的代码的过程中,我在想,为什么copy constructor的参数是个引用,而不是普通的传值呢?想想,其实好简单的道理,我在写一个object的copy constructor,如果一个方法调用使用该object作为形参,那么copy constructor 就会被调用。当然copy constructor本身也是个方法,如果copy 也是以object作为形参,那么岂不是“死循环”了——copy constructor调用copy constructor,没完没了啊?

同时也重温了下引用和指针。
看了http://www.uml.org.cn/c++/201010123.asp 的分析,恍然大悟啊。。。
原来引用和指针本质是一样的东西,都是存放目标的地址值,只是操作这两种类型的时候,编译器执行不同的操作。操作引用的时候,会间接寻址,操作寻址后的对象,而操作指针,就是操作地址值本身,而不是地址值指向的地方。

相关推荐

    深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    用同一个类的源对象构造一个目标对象时,会调用拷贝构造函数来构造目标对象,如果没有定义拷贝构造函数,将调用类的默认拷贝函数来构造目标对象。2 . 当一个函数的返回值为一个类的对象时,如果在调用函数中,没有...

    C++中复制构造函数和重载赋值操作符总结

    这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义; 2.复制构造函数和重载赋值操作符的调用时机; 3.复制构造函数和重载赋值操作符的实现要点; 4....

    C++ 赋值构造函数注意点介绍

    初始化和赋值问题详解C++ 拷贝构造函数和赋值运算符详解C++中对构造函数和赋值运算符的复制和移动操作C++中复制构造函数和重载赋值操作符总结深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结...

    JS构造函数的执行过程

    通过new操作符调用的函数为构造函数,会构造出一个类的实例 一个函数直接调用则为普通函数调用方式,用new调用则为构造函数调用方式 function Fn(name,age){ let n = 5; this.name=name; this.age=age; } Fn(a,10...

    C++Primer视频(高级)下载地址

    10.13章 复制构造函数和赋值操作符 11.13章 析构函数 12.13章 深复制、浅复制 13.13章 管理指针成员 14.14章 重载操作符的定义 15.14章 重载输入输出操作符 16.14章 重载算术操作符 17.14章 重载关系...

    c++智能指针的实现

    对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数减至0,则删除对象),并增加右操作数所指对象的引用计数; 调用析构函数时,减少引用计数(如果引用计数减至0,则删除基础对象); ...

    C++智能指针实现

    对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础...

    C++ Primer第四版【中文高清扫描版】.pdf

    5.4.3 复合赋值操作符 139 5.5 自增和自减操作符 140 5.6 箭头操作符 142 5.7 条件操作符 143 5.8 sizeof操作符 144 5.9 逗号操作符 145 5.10 复合表达式的求值 145 5.10.1 优先级 145 5.10.2 结合性 146 5.10.3 求...

    Effective.C++.中文第二版.50条款doc文档.chm

    条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符 条款12: 尽量使用初始化而不要在构造函数里赋值 条款13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同 条款14: 确定基类有虚析构...

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    14.2.1 派生类中的赋值操作符和复制 构造函数 426 14.2.2 派生类的析构函数 426 14.2.3 保护继承和私有继承 436 14.2.4 多继承 437 第15章 多态与虚函数 442 15.1 虚函数基础 442 15.1.1 后绑定 442 15.1.2 ...

    C++编程思想习题

    6.2.1预先了解操作符重载 6.2.2插入符与提取符 6.2.3通常用法 6.2.4面向行的输入 6.3文件输入输出流 6.4输入输出流缓冲 6.5在输入输出流中查找 6.6strstreams 6.6.1为用户分配的存储 6.6.2自动存储分配 6.7输出流...

    传智播客扫地僧视频讲义源码

    19_深拷贝和浅拷贝_默认的等号操作符也是浅拷贝_传智扫地僧 20_构造函数的初始化列表 21_强化训练1_构造和析构调用顺序 22_强化训练2_匿名对象生命周期 23_强化训练3_构造中调用构造(产生匿名对象)_传智扫地僧 24_...

    新手学习C++入门资料

    这些关键字能作为函数和变量的标识符在C程序中使用,尽管C++包含了所有的C,但显然没有任何C++编译器能编译这样的C程序。 C程序员可以省略函数原型,而C++不可以,一个不带参数的C函数原型必须把void写出来。而C++...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

     13.6.2 移动构造函数和移动赋值运算符 473  13.6.3 右值引用和成员函数 481  小结 486  术语表 486  第14章 操作重载与类型转换 489  14.1 基本概念 490  14.2 输入和输出运算符 494  14.2.1 重载输出...

    程序设计教程 陈家骏等编著

    2.4.4 赋值操作符 36 2.4.5 其它操作符 37 2.5 表达式 38 2.5.1 表达式的构成与分类 39 2.5.2 操作符的优先级和结合性 39 2.5.3 表达式中的类型转换 41 2.5.4 表达式的副作用问题 42 2.5.5 表达式结果的输出 42 2.6 ...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

     13.6.2 移动构造函数和移动赋值运算符 473  13.6.3 右值引用和成员函数 481  小结 486  术语表 486  第14章 操作重载与类型转换 489  14.1 基本概念 490  14.2 输入和输出运算符 494  14.2.1 重载输出...

    c++中new和delete操作符用法

    当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,第二步就会被省略。 new用法: 1. 开辟单变量地址空间...

    Python核心编程(第二版).pdf (压缩包分2部分,第二部分)

     3.2.1 赋值操作符   3.2.2 增量赋值   3.2.3 多重赋值   3.2.4 “多元”赋值   3.3 标识符   3.3.1 合法的python标识符   3.3.2 关键字   3.3.3 内建   3.3.4 专用下划线标识符   3.4...

Global site tag (gtag.js) - Google Analytics