您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么從C++的角度分析PYTHON的深淺拷貝”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么從C++的角度分析PYTHON的深淺拷貝”吧!
其實(shí)python中的深COPY和淺COPY和C\C++中是一樣的,畢竟python底層是C/C++做的,這方面保留了
C\C++的原理,對于類或者結(jié)構(gòu)體復(fù)制構(gòu)造函數(shù)等號(=)操作符保留了淺COPY,當(dāng)然我們可以自定義
這些函數(shù)。我們先從C++的簡單的復(fù)制構(gòu)造函數(shù)等號(=)操作符的例子開始
#include<iostream> #include <stdlib.h> #include <string.h> using namespace std; class testcy { private: char* a; unsigned int b; public: testcy(const char* inc) { a = new char[strlen(inc)+1]; strcpy(a,inc); b = 1; } testcy() { a= NULL; b = 0; } testcy(const testcy &in) //淺copy 構(gòu)造函數(shù) { this->a = in.a; this->b = in.b; } testcy& operator=(const testcy& in)//淺=值操作符重載 { this->a = in.a; this->b = in.b; } void print() { cout<<this->a<<" "; cout<<this->b<<endl; } void modify(const char* in,const int in2) { if(strlen(a) < strlen(in)) { cout<< "error:much lenth than point a char"<<endl; exit(1); } else { for(int i=0;i<strlen(in);i++) { *(a+i) = *(in+i); } } b = in2; } }; int main(void) { testcy a("123123"); testcy b = a; testcy c ; c = a; cout<<"source data:"<<endl; cout<<"string int"<<endl; a.print(); b.print(); c.print(); cout<<"after only change a:"<<endl; cout<<"string int"<<endl; a.modify("asd",2); a.print(); b.print(); c.print(); }
非常簡單就是為了演示淺COPY輸出如下:
source data: string int 123123 1 123123 1 123123 1 after only change a: string int asd123 2 asd123 1 asd123 1
我們可以看到在修改a的數(shù)據(jù)后b、c的數(shù)據(jù)string數(shù)據(jù)也更改了,但是簡單類型int沒有更改。那么我們用內(nèi)存四區(qū)圖來描述
123.jpg
圖中a->a當(dāng)然就是整形,但是a->b是指針其指針的值0XB0120存在棧中但是實(shí)際指向的數(shù)據(jù)存在堆中,
而變量b->b,c->b指向了同一塊內(nèi)存 導(dǎo)致一改全部都改了,但是a->a,b->a,c->a確實(shí)單獨(dú)的在棧上了的
沒影響。其實(shí)這里我們只要修改淺COPY為深COPY改變其實(shí)現(xiàn)即可比如
testcy(const testcy &in) //深copy 構(gòu)造函數(shù) { this->a = new char[strlen(in.a)+1]; strcpy(this->a,in.a); this->b = in.b; }
我們要做的不僅僅是要指針相等而是要將內(nèi)存重新分配。注意本測試程序沒有寫析構(gòu)函數(shù)。
下面我們來看看python的淺列表拷貝
import copy a = ['t1','t2','t3','t4'] b = a print("source data") print(a); print(b); a[0] = 'gao' print("after change:") print(a); print(b);
source data ['t1', 't2', 't3', 't4'] ['t1', 't2', 't3', 't4'] after change: ['gao', 't2', 't3', 't4'] ['gao', 't2', 't3', 't4']
確實(shí)如此,修改了列表元素a[0]的值b列表也修改了,我們有了C++的那張圖這個(gè)就很好理解了,他們是
指向同一塊內(nèi)存堆區(qū)。我們應(yīng)該使用
a = ['t1','t2','t3','t4'] b = copy.deepcopy(a)
從這個(gè)方法的命名我們也可以看到這是深copy,其原理已經(jīng)在C++代碼進(jìn)行了剖析
另外如下:
a = [['t1','t10'],'t2','t3','t4'] b = a.copy() print("source data") print(a); print(b); a[0][0] = 'gao' print("after change:") print(a); print(b);
source data [['t1', 't10'], 't2', 't3', 't4'] [['t1', 't10'], 't2', 't3', 't4'] after change: [['gao', 't10'], 't2', 't3', 't4'] [['gao', 't10'], 't2', 't3', 't4']
a.copy()只是對第一層進(jìn)行copy,第二層在python里面實(shí)現(xiàn)應(yīng)該也是指針或者引用,一樣的會出問題。
所以copy的時(shí)候我們盡量使用copy.deepcopy(a)來得到正確的數(shù)據(jù)當(dāng)然根據(jù)實(shí)際需求定。
可以看到C/C++是理論基礎(chǔ),有了這些理論P(yáng)YTHON中的很多現(xiàn)象很好理解。
感謝各位的閱讀,以上就是“怎么從C++的角度分析PYTHON的深淺拷貝”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么從C++的角度分析PYTHON的深淺拷貝這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。