- 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第2章类和对象2011(2hx3)
3.对象在内存的存放 用类去定义对象时,系统会为每一个对象分配存储空间。 在C++中,每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括成员函数代码所占用的存储空间。 [程序分析] 例8-2 对象在内存存放情况示例 [例] class Test { private: int num; float fl; public: Test(int, float); Test( test ); }; Test::Test(int n, float f) { num=n; fl=f; } 当用一个对象去初始化该类的另一个对象时; Test a1; // 调用默认构造函数对a1进行初始化 Test a2(a1); // 调用复制构造函数使用a1初始化a2,也可以写成Test a2=a1; 如果函数的形参是类的对象,调用函数进行形参和实参的结合时; void fun1(Test t) { … } int main() { test a1; fun1(a1); // 调用时将创建形参对象t,并调用复制构造函数用a1初始化t return 0;} 如果函数的返回值是类的对象,函数调用完成时。 Test fun2() { Test t; … return t; } int main() { Test a1; a1=fun2(); // 在fun2返回对象时,会调用复制构造函数,复制出一临时对象, // 然后将此临时对象“赋值”给a1 return 0; 当一个类没有自定义的复制构造函数的时候,系统会自动提供一个默认的复制构造函数,来完成复制工作。 例如,类Test的默认复制构造函数具有以下形式: Test ::Test(const Test t) { x=t.x; y=t.y; } 这个系统自动产生的“默认复制构造函数”通常很简单,仅仅使用“老对象”的数据成员的值对“新对象”的数据成员一一进行赋值。 在对象复制时,只是对对象中的数据成员进行简单的赋值的方式称为浅复制。 默认复制构造函数执行的就是浅复制。 浅复制可能带来严重问题-----? [问题] 有如下的程序段: class Country { public: Country() { landArea=0; name=NULL; } Country(double x,char *str) // 构造函数,name指向堆中分配的一空间 { landArea=x; name=new char[strlen(str)+1]; strcpy(name,str); } ~Country() { // 析构函数,释放动态分配的空间 if(name != NULL) { delete name; } } 这段代码在运行结束之前,会出现一个运行错误。这是因为在使用c1初始化c2时,由于执行的是默认复制构造函数(浅复制),只是将数据成员的值进行赋值,此时c1.name和c2.name具有相同的值,也就是这两个指针指向了堆里的同一个空间。 [解决方法] 在类Country中显式定义一个复制构造函数: Country(const Country c) { landArea = c.landArea; name=new char[strlen(c.name)+1]; // 为新对象重新动态分配空间 strcpy(name,c.name); } 这个显式定义的复制构造函数使用的是“深复制”。 在“深复制”的情况下,对于对象中的动态成员,不仅仅简单地赋值,而是重新动态分配空间。这样,执行语句Country c2(c1);将调用显式定义的复制构造函数完成对象的初始化。此时,c1的name和c2的name各自指向一段内存空间,但它们指向的空间具有相同的内容 。 [小结]: 数据成员 非const成员函数 const成员函
文档评论(0)