- 1、本文档共7页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
?
HYPERLINK /totty2006/article/details/5003536 \o C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝 C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝
HYPERLINK /alexusli/archive/2008/08/27/1277683.html C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝
关键词:构造函数,浅拷贝,深拷贝,堆栈(stack),堆heap,赋值运算符摘要:????在面向对象程序设计中,对象间的相互拷贝和赋值是经常进行的操作。??如果对象在申明的同时马上进行的初始化操作,则称之为拷贝运算。例如:????????class1 A(af); class1?B=A;?????此时其实际调用的是B(A)这样的浅拷贝操作。???如果对象在申明之后,在进行的赋值运算,我们称之为赋值运算。例如:????????class1 A(af); class1 B;????????B=A;????????此时实际调用的类的缺省赋值函数B.operator=(A);????????不管是浅拷贝还是赋值运算,其都有缺省的定义。也就是说,即使我们不overload这两种operation,仍然可以运行。那么,我们到底需不需要overload这两种operation 呢?????????答案就是:一般,我们我们需要手动编写析构函数的类,都需要overload 拷贝函数和赋值运算符。 ?????????下面介绍类的赋值运算符1.C++中对象的内存分配方式????????在C++中,对象的实例在编译的时候,就需要为其分配内存大小,因此,系统都是在stack上为其分配内存的。这一点和C#完全不同!千 万记住:在C#中,所有类都是reference type,要创建类的实体,必须通过new在heap上为其分配空间,同时返回在stack上指向其地址的reference.????????因此,在C++中,只要申明该实例,在程序编译后,就要为其分配相应的内存空间,至于实体内的各个域的值,就由其构造函数决定了。????例如:????
class?A{public:????A()????{
???????? name = new char[1];?//These code is added?By CR???????? *name = /0;????}????A(int?id,char?*t_name)????{????_id=id;????name=new?char[strlen(t_name)+1];????strcpy(name,t_name);????}????private:????????char *name;????????int _id;}int?main(){A?a(1,herengang);A?b;}
在程序编译之后,a和b在stack上都被分配相应的内存大小。只不过对象a的域都被初始化,而b则都为随机值。其内存分配如下:2. 缺省情况下的赋值运算符????如果我们执行以下:????b=a;????????则其执行的是缺省定义的缺省的赋值运算。所谓缺省的赋值运算,是指对象中的所有位于stack中的域,进行相应的复制。但是,如果对象有位于heap上的域的话,其不会为拷贝对象分配heap上的空间,而只是指向相同的heap上的同一个地址。????????执行b=a这样的缺省的赋值运算后,其内存分配如下:????????因此,对于缺省的赋值运算,如果对象域内没有heap上的空间,其不会产生任何问题。但是,如果对象域内需要申请heap上的空间,那么在析构对象的时候,就会连续两次释放heap上的同一块内存区域,从而导致异常。
????~A()????{????????????????delete?name;????}
3.解决办法--重载(overload)赋值运算符????????因此,对于对象的域在heap上分配内存的情况,我们必须重载赋值运算符。当对象间进行拷贝的时候,我们必须让不同对象的成员域指向其不同的heap地址--如果成员域属于heap的话。????因此,重载赋值运算符后的代码如下:
class?A{public:????A()????{????}????A(int?id,char?*t_name)????{????????_id=id;????????name=new?char[strlen(t_name)+1];????????strcpy(name,t_name);????}????????A?op
文档评论(0)