




免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
我的心得:对结构和对象的参数传递和函数返回,尽量用引用,不要用值传递,一是可以节省内存开销,二是避免再创造临时对象或结构时,引起错误(特别是包含动态分配成员时)拷贝构造函数拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的参数(对象的引用)是不可变的(const类型)。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。一般来说,调用拷贝构造函数的情形在C+中,下面三种对象需要调用拷贝构造函数: 1) 一个对象以值传递的方式传入函数体; 2) 一个对象以值传递的方式从函数返回; 3) 一个对象需要通过另外一个对象进行初始化; 如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作符共同实现的。描述拷贝构造函数和赋值运算符的异同的参考资料有很多。 拷贝构造函数不可以改变它所引用的对象,其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环直至栈溢出(Stack Overflow)。除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。 隐式的拷贝构造函数如果在类中没有显式的声明一个拷贝构造函数,那么,编译器会自动生成一个来进行对象之间的位拷贝(Bitwise Copy)。这个隐含的拷贝构造函数简单的关联了所有的类成员。注意到这个隐式的拷贝构造函数和显式声明的拷贝构造函数的不同在于对成员的关联方式。显式声明的拷贝构造函数关联的只是被实例化的类成员的缺省构造函数,除非另外一个构造函数在类初始化或构造列表的时候被调用。 拷贝构造函数使程序更有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。设计拷贝构造函数是一个良好的风格,即使是编译系统会自动为你生成默认拷贝构造函数。事实上,默认拷贝构造函数可以应付许多情况。 示例以下讨论中将用到的例子: class CExample public: CExample()pBuffer=NULL; nSize=0; CExample()delete pBuffer; void Init(int n) pBuffer=new charn; nSize=n; private: char *pBuffer; /类的对象中包含指针,指向动态分配的内存资源 int nSize; ; 这个类的主要特点是包含指向其他资源的指针。 pBuffer指向堆中分配的一段内存空间。 int main(int argc, char* argv) CExample theObjone; theObjone.Init(40); /现在需要另一个对象,需要将他初始化成对象一的状态 CExample theObjtwo=theObjone; . 语句CExample theObjtwo=theObjone;用theObjone初始化theObjtwo。 其完成方式是内存拷贝,复制所有成员的值。 完成后,theObjtwo.pBuffer=theObjone.pBuffer。 即它们将指向同样的地方,指针虽然复制了,但所指向的空间并没有复制,而是由两个对象共用了。这样不符合要求,对象之间不独立了,并为空间的删除带来隐患。所以需要采用必要的手段来避免此类情况。 回顾一下此语句的具体过程:首先建立对象theObjtwo,并调用其构造函数,然后成员被拷贝。 可以在构造函数中添加操作来解决指针成员的问题。 所以C+语法中除了提供缺省形式的构造函数外,还规范了另一种特殊的构造函数:拷贝构造函数,上面的语句中,如果类中定义了拷贝构造函数,这对象建立时,调用的将是拷贝构造函数,在拷贝构造函数中,可以根据传入的变量,复制指针所指向的资源。 拷贝构造函数的格式为:构造函数名(对象的引用) 提供了拷贝构造函数后的CExample类定义为: class CExample public: CExample()pBuffer=NULL; nSize=0; CExample()delete pBuffer; CExample(const CExample&); /拷贝构造函数 void Init(int n) pBuffer=new charn; nSize=n; private: char *pBuffer; /类的对象中包含指针,指向动态分配的内存资源 int nSize; ; CExample:CExample(const CExample& RightSides) /拷贝构造函数的定义 nSize=RightSides.nSize; /复制常规成员 pBuffer=new charnSize; /复制指针指向的内容 memcpy(RightSides.pBuffer,pBuffer,nSize*sizeof(char); /构造函数是没有返回值,没有return语句的这样,定义新对象,并用已有对象初始化新对象时,CExample(const CExample& RightSides)将被调用,而已有对象用别名RightSides传给构造函数,以用来作复制。原则上,应该为所有包含动态分配成员的类都提供拷贝构造函数。 下面介绍拷贝构造函数的另一种调用。当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调同拷贝构造函数。例如: BOOL testfunc(CExample obj); testfunc(theObjone); /对象直接作为参数。 BOOL testfunc(CExample obj) /针对obj的操作实际上是针对复制后的临时拷贝进行的 还有一种情况,也是与临时对象有关的 当函数中的局部对象被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用 CTest func() CTest theTest; return theTest; 下面的代码与上例相似 INT MAIN(INT ARGC, CHAR* ARGV) CEXAMPLE THEOBJONE; THEOBJONE.INIT(40); CEXAMPLE THEOBJTHREE; THEOBJTHREE.INIT(60); /现在需要一个对象赋值操作,被赋值对象的原内容被清除,并用右边对象的内容填充。 THEOBJTHREE=THEOBJONE; RETURN 0; 也用到了=号,但与一、中的例子并不同,一、的例子中,=在对象声明语句中,表示初始化。更多时候,这种初始化也可用括号表示。 例如 CEXAMPLE THEOBJONE(THEOBJTWO); 而本例子中,=表示赋值操作。将对象THEOBJONE的内容复制到对象THEOBJTHREE;,这其中涉及到对象THEOBJTHREE原有内容的丢弃,新内容的复制。 但=的缺省操作只是将成员变量的值相应复制。旧的值被自然丢弃。 由于对象内包含指针,将造成不良后果:指针的值被丢弃了,但指针指向的内容并未释放。指针的值被复制了,但指针所指内容并未复制。 因此,包含动态分配成员的类除提供拷贝构造函数外,还应该考虑重载=赋值操作符号。 类定义变为: CLASS CEXAMPLE . CEXAMPLE(CONST CEXAMPLE&); /拷贝构造函数 CEXAMPLE& OPERATOR = (CONST CEXAMPLE&); /赋值符重载 ./必须是返回对象的本身,否则又会发生一次赋值! ; /赋值操作符重载 CEXAMPLE & CEXAMPLE:OPERATOR = (CONST CEXAMPLE& RIGHTSIDES) IF (THIS = &RIGHTSIDES) / 如果自己给自己赋值则直接返回 RETURN *THIS; NSIZE=RIGHTSIDES.NSIZE;  /复制常规成员 CHAR *TEMP=NEW CHARNSIZE; /复制指针指向的内容 MEMCPY(TEMP,RIGHTSIDES.PBUFFER,NSIZE*SIZEOF(CHAR); DELETE PBUFFER;   /删除原指针指向内容(将删除操作放在后面,避免X=X特殊情况下,内容的丢失) PBUFFER=NULL; PBUFFER=TEMP;      /建立新指向 RETURN *THIS 拷贝构造函数和赋值函数的功能是相同的,为了不造成重复代码,拷贝构造函数实现如下: CExample:CExample(const CExample& RightSides) *this=RightSides; /调用重载后的= 拷贝构造与构造区别class 类名 public: 类名(形参参数)/构造函数 类名(类名&对象名)/拷贝构造函数 , ; 拷贝构造函数的实现: 类名:类名(类名&对象名)/拷贝构造函数的实现 函数体
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 入队教育主题课件
- 健康知识培训主持开场白课件
- 伞的秘密教学课件
- 邮箱指引文件管理办法
- 配电反违章管理办法
- 2025年住房拆迁面试题及答案
- 澄海民间资金管理办法
- 电网现场违章管理办法
- 甘肃地区礼金管理办法
- 国家公务员基础知识题库大全(附答案)
- 特警业务知识考试题库200题(含各题型)
- 热压机说明书范文
- GB/T 39616-2020卫星导航定位基准站网络实时动态测量(RTK)规范
- GB/T 3620.1-2007钛及钛合金牌号和化学成分
- GB/T 19519-2014架空线路绝缘子标称电压高于1 000 V交流系统用悬垂和耐张复合绝缘子定义、试验方法及接收准则
- 计算机网络技术论文(优秀6篇)
- 化学史课件讲课教案
- 心率与高血压培训课件
- 旅游客源国地区概况(第三版)第03章亚洲客源国概况(下)
- 智慧审计综合管理平台解决方案
- 宝钢产品质量证明书模板
评论
0/150
提交评论