一直对C++的复制(Copy)、赋值(Assign)操作比较困惑,现在看书的时候看到了,就把它顺便记下来。

一、什么时候触发

一下代码可以熟悉什么时候触发复制操作,以及什么时候触发赋值操作:

// testCopy.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include <string> using namespace std;
class testCopy
{
public:
testCopy():a()
{
cout<<"enter constructor"<<endl;
};
//重载赋值操作符
testCopy& operator=(const testCopy& t)
{
cout<<"enter operator="<<endl;
a = t.a;
return *this;
}
//复制构造函数
testCopy(const testCopy& t):a(t.a)
{
cout<<"enter copy constructor"<<endl;
}
~testCopy()
{
cout<<"enter destructor"<<endl;
}
int a;
}; void f1(testCopy t2)
{
cout<<"enter f1"<<endl;
} testCopy f2()
{
cout<<"enter f2"<<endl;
testCopy t3;//调用普通构造函数
return t3;//以类实例为非引用类型返回值时触发复制构造
} int _tmain(int argc, _TCHAR* argv[])
{
cout<<"t1"<<endl;
testCopy t1;//调用普通构造函数
cout<<"t2"<<endl;
testCopy t2(t1);//直接以类实例为参数初始化另一个类实例时触发复制构造
cout<<"t3"<<endl;
testCopy t3;//调用普通构造函数
t3 = t1;//将类实例赋值给另一个类实例时触发赋值操作
cout<<"f1"<<endl;
f1(t1);//以类实例为非引用类型的参数传递给函数时调用复制构造
cout<<"f2"<<endl;
testCopy t4;//调用普通构造函数
t4 = f2();//将类实例赋值给另一个类实例时触发赋值操作
cout<<"end"<<endl;
return ;
}

输出结果如下:

t1
enter constructor
t2
enter copy constructor
t3
enter constructor
enter operator=
f1
enter copy constructor
enter f1
enter destructor
f2
enter constructor
enter f2
enter constructor
enter copy constructor
enter destructor
enter operator=
enter destructor
end
enter destructor
enter destructor
enter destructor
enter destructor

二、复制、赋值、析构函数重写的必要性

上面的例子不足以说明重写复制、赋值、析构的重要性,当类中需要动态分配内存时,重要性就体现出来了:

class testCopy2
{
public:
testCopy2():buf(new char[])
{
cout<<"enter constructor"<<endl;
};
//重载赋值操作符
testCopy2& operator=(const testCopy2& t)
{
//如果不重写赋值构造函数,那么多个类实例之间的buf指向的是同一片内存。
cout<<"enter operator="<<endl;
memcpy(buf,t.buf,);
return *this;
}
//复制构造函数
testCopy2(const testCopy2& t):buf(new char[])
{
cout<<"enter copy constructor"<<endl;
memcpy(buf,t.buf,);
//如果不重写复制构造函数,那么多个类实例之间的buf指向的是同一片内存。
}
~testCopy2()
{
//如果不重写析构函数,那么buf指针内存不会被删除。
cout<<"enter destructor"<<endl;
delete buf;
}
char* buf;
};

三、一些规则

1. 如果一个类需要一个析构函数,那么它一定需要重载复制和赋值操作。

2. 如果一个类需要重载复制操作,那么它一定需要重载赋值操作,反之同成立。

3. 如果一个类需要重载复制和赋值操作,但是不一定需要重载析构操作。

四、相关下载

代码

C++中的复制、赋值、析构的更多相关文章

  1. php中引用和赋值的区别主要在哪里

    php中引用和赋值的区别 <pphp 的引用允许用两个变量来指向同一个内容. 相当于他们可以是 不同的名字,却可以指向 同一个 物理空间. 赋值,它实际上意味着把右边表达式的值赋给左边的运算数. ...

  2. [置顶] js中如何复制一个对象,如何获取所有属性和属性对应的值

    在js中如何复制一个对象,例如如下一个js对象. 如果知道这个对象的所有属性自然就可以重新new一个,然后对每个属性赋值,就可以做到,但如果不知道呢?如何创建一个内容相同 的对象呢? var obj= ...

  3. python中深复制和浅复制区别

    在python中,对象赋值实际上是对象的的引用,当创建一个对象,然后把它赋值给另外一个变量的时候,python没有拷贝这个对象,而只是拷贝了这个对象的引用,多以就出现了浅复制,即复制后原对象改变后,复 ...

  4. Android中的复制粘贴

    Android中的复制粘贴 The Clipboard Framework 当使用clipboard framework时,把数据放在一个剪切对象(clip object)里,然后这个对象会放在系统的 ...

  5. 怎样简单灵活地将DataTable中的数据赋值给model

    最近在做的一个项目中,有13个方法都需要用到同一种处理方式:通过SQL语句从数据库获取一条指定的数据,并将该数据中的每个值都赋值给一个model,再将这个model中的数据通过微信发送出去.每个方法都 ...

  6. C语言中结构体赋值问题的讨论

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  7. c#.net循环将DataGridView中的数据赋值到Excel中,并设置样式

    Microsoft.Office.Interop.Excel.Application excel =                new Microsoft.Office.Interop.Excel ...

  8. DataTable中的数据赋值给model z

    create table memberinfo ( member_id int, member_name varchar(20), member_birthday varchar(50) ) go / ...

  9. Verilog-FPGA硬件电路设计之一——if语句优先级(always块中的阻塞赋值生成的组合逻辑电路是按照顺利执行的)

    出处:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM 综合软件:Quartus II 一.有优先级的if语句 if..else if.. else i ...

  10. (转载)php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗?

    (转载)http://s.yanghao.org/program/viewdetail.php?i=184313 php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗? class block ...

随机推荐

  1. 09.C#委托转换和匿名方法(五章5.1-5.4)

    今天将书中看的,自己想的写出来,供大家参考,不足之处请指正.进入正题. 在C#1中开发web form常常会遇到使用事件,为每个事件创建一个事件处理方法,在将方法赋予给事件中,会使用new Event ...

  2. [C#]二维码(QR Code)生成与解析

    写在前面 经常在大街上听到扫码送什么什么,如果真闲着没事,从头扫到位,估计书包都装满了各种东西.各种扫各种送,太泛滥了.项目中从没接触过二维码的东东,最近要使用,就扒了扒网络,发现关于解析二维码的类库 ...

  3. MySQL 索引背后的数据结构及算法原理

    本文转载自http://blog.jobbole.com/24006/ 摘要本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引 ...

  4. Sublime Text 3 Build 3065 All System CracKed By Hmily[LCG]

    Sublime Text 3 Build 3065 All System CracKed By Hmily[LCG] <ignore_js_op> 程序员文本编辑器 Sublime Tex ...

  5. Nginx简单实现网站的负载均衡

    在大型网站搭建时,都会考虑如果用户量每日不断增加,大量的并发访问,会不会给网站.数据库带来崩盘的灾难.今天我们就讨论一下,现实中如何解决这些问题的一套最为容易实现的方案. 控制并发,大家都会首先考虑的 ...

  6. 使用ssis完成excel的数据导入

    SSIS(SQL Server Integration Service)是从MS SQL 2005开始引入的,是一种ETL(Extract Transform Load)工具,SSIS比普通的ETL更 ...

  7. 【BZOJ-1797】Mincut 最小割 最大流 + Tarjan + 缩点

    1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1685  Solved: 724[Submit] ...

  8. Project facet Java version 1.8 is not supported解决记录

    一看知道是因为jdk版本不一致所导致,如何解决? 方法一: 选中项目 Properties , 选择 Project Facets,右击选择 Java , Change Version  方法二: 在 ...

  9. this的使用

    1.使用this调用本类中的属性 class Person{ private String name; private int age; public Person(String name,int a ...

  10. python学习易错点1

    1.>>> d = {'x': 'A', 'y': 'B', 'z': 'C' } >>> for k, v in d.iteritems(): ... print ...