C++拷贝对象
簡(jiǎn)介
對(duì)象的創(chuàng)建中,常常有這樣的需求,就是把對(duì)象復(fù)制一份。
而復(fù)制有三種方法:
1.通過初始化來復(fù)制
例如:Object o1(10); Object o2=o1;
2.通過賦值來復(fù)制
例如:Object o1(10); Object o2; o2=o1;
3.通過默認(rèn)拷貝函數(shù)來復(fù)制
例如:Object o1(10); Object o2(o1);
實(shí)際上,第一種方法內(nèi)部原理是執(zhí)行了第三種的拷貝函數(shù),默認(rèn)的拷貝函數(shù)是淺拷貝,也就是說只能對(duì)基本類型數(shù)值進(jìn)行拷貝
Object類如下:
class Object {private:int _num;public:Object(int num){_num=num;}};分析
第一種復(fù)制對(duì)象方法原理(初始化復(fù)制)
1.首先 Object o2=o1 這句是先執(zhí)行了o1的默認(rèn)拷貝函數(shù)
此處o1的默認(rèn)拷貝函數(shù)申明為: Object(const Object& obj),該實(shí)現(xiàn)體為編譯器默認(rèn)的淺復(fù)制方法實(shí)現(xiàn),因此對(duì)于含有復(fù)雜變量的類,需要重寫該函數(shù)
2.然后執(zhí)行o1的拷貝函數(shù)后返回一個(gè)匿名對(duì)象
3.最后將該匿名對(duì)象命名為o2
第二種復(fù)制方法原理(賦值復(fù)制)
*該原理較為簡(jiǎn)單,就是直接將簡(jiǎn)單基本變量值拷貝一份賦值給拷貝對(duì)象
第三種復(fù)制方法原理(拷貝函數(shù)復(fù)制)
*第一種原理已解釋
實(shí)例
代碼
Object.h
class Object {private:int _num;public:Object(int num){_num=num;}int getNum(){return _num;}};main.cpp
#include <iostream> #include "Object.h" using namespace std;int main(int argc, char** argv) {Object o1(10);Object o2=o1;cout<<o2.getNum()<<endl;Object oo1(20);Object oo2(10);oo2=oo1;cout<<oo2.getNum()<<endl;Object ooo1(30);Object ooo2(ooo1);cout<<ooo2.getNum()<<endl;return 0; }運(yùn)行結(jié)果
提升
代碼
Object.h
#ifndef OBJECT_H #define OBJECT_H#include <stdlib.h> #include <string.h>class Object {private:char *_name;public:Object(char *name){_name=(char*)malloc(sizeof(char)*(strlen(name)+1));strcpy(_name,name);}};#endifmain.cpp
#include <iostream> #include "Object.h" using namespace std;void Test() {Object o1("test");Object o2(o1); }int main(int argc, char** argv) {Test();return 0; }*這段代碼在較為嚴(yán)格的編譯器中會(huì)報(bào)錯(cuò),這是因?yàn)槟J(rèn)拷貝函數(shù)是淺拷貝,對(duì)基本的值進(jìn)行拷貝
*然而o2拷貝o1的值時(shí),拷貝的是_name的值,在棧中也就是字符串的地址值,因此拷貝后的o2的_name只是引用了o1的_name指向的字符串
*因此在Test函數(shù)結(jié)束時(shí),首先o2被析構(gòu),其_name指向的字符串被回收。然后o1被析構(gòu),其_name指向的字符已在o2析構(gòu)時(shí)被回收,因此o1的_name是野指針,因此產(chǎn)生錯(cuò)誤。
改進(jìn)代碼
Object.h
#ifndef OBJECT_H #define OBJECT_H#include <stdlib.h> #include <string.h>class Object {private:char *_name;int _num;public:Object(int num,char *name){_num=num;_name=(char*)malloc(sizeof(char)*(strlen(name)+1));strcpy(_name,name);}Object(const Object& obj){_name=(char*)malloc((sizeof(char)*strlen(obj._name)+1));strcpy(_name,obj._name);}};#endif轉(zhuǎn)載于:https://www.cnblogs.com/pwc1996/p/5957865.html
總結(jié)
- 上一篇: [ 1001] 动态开辟二维数组的说明
- 下一篇: springmvc学习笔记--Inter