C++?拷貝構(gòu)造函數(shù)與賦值的區(qū)別
拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)的也是一種構(gòu)造函數(shù),它的作用是將一個(gè)類的成員拷貝到另一個(gè)類中,類似于賦值。拷貝構(gòu)造函數(shù)分為深拷貝和淺拷貝。
先來定義一個(gè)拷貝構(gòu)造函數(shù)(構(gòu)造函數(shù)可以重載),看招:
#include<iostream> using namespace std; class date { public: date(int year=0, int month=0, int day=0) { _year = year; _month = month; _day = day; } date(const date& d)//拷貝構(gòu)造函數(shù) { this->_year = d._year; this->_month = d._month; this->_day = d._day; } void print() { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; };
將一個(gè)類拷貝到另一個(gè)類中,自然是需要對應(yīng)的參數(shù)的,參數(shù)就是類,這里可以傳遞指針,引用更好,只是傳值形參的話,會造成無限遞歸。
拷貝構(gòu)造函數(shù)的使用方法
拷貝構(gòu)造函數(shù)的使用:
1.使用();2.使用'=';像這樣
拷貝構(gòu)造函數(shù)與賦值運(yùn)算符的區(qū)別
那么拷貝構(gòu)造函數(shù)和賦值運(yùn)算符有什么區(qū)別呢,先來看一段代碼對比一下:
int main() { date d1(20244, 4, 24); date d2=d1; date d3; d3= d1;//編譯器會自動將其轉(zhuǎn)化為d3(d1); return 0; }
這里d2采用的拷貝構(gòu)造函數(shù)的方式,d3采用賦值的方式,通過觀察,我們可以發(fā)現(xiàn),前者是創(chuàng)造變量時(shí)就對類進(jìn)行了賦值,這個(gè)賦值叫做初始化,而后者是先定義好的類,后續(xù)賦值,在賦值之前是已經(jīng)將變量創(chuàng)建好的;
談深拷貝和淺拷貝
先說淺拷貝
淺拷貝
淺拷貝就是對成員變量進(jìn)行一一對應(yīng)賦值,來看一個(gè)代碼:
#include<iostream> using namespace std; class date { public: date(int a=1,int b=1) { _a = a; _b = b; } date(const date& d) { _a = d._a;//成員變量簡單的賦值 _b = d._b; } void print() { cout << _a << ',' << _b << endl; } ~date() { cout << "~date" << endl; } private: int _a; int _b; }; int main() { date d1(2,5); date d2(d1); d2.print(); return 0; }
在這個(gè)代碼中,在對d2進(jìn)行初始化的時(shí)候,是將d1的成員變量對d進(jìn)行了賦值;最后代碼結(jié)束存在兩次析構(gòu),分別是d2和d1的;
注意:
對于簡單的成員變量進(jìn)行簡單的復(fù)制操作并無大礙,但是如果是指針類型的變量就會出現(xiàn)問題;看代碼;
#include<iostream> using namespace std; class date { public: date(int b=1) { _a =new int[4]; _b = b; } date(const date& d) { _a = d._a; _b = d._b; } void print() { cout << _a << ',' << _b << endl; } ~date() { free(_a);//拷貝后兩個(gè)成員變量都指向同一塊空間,會造成多次析構(gòu) cout << "~date" << endl; } private: int* _a; int _b; }; int main() { date d1(5); date d2(d1); d2.print(); return 0; }
代碼中_a為指針類型,初始化是對其進(jìn)行開辟空間;代碼結(jié)束對類進(jìn)行析構(gòu),但是問題來了,淺拷貝只是簡單的賦值,針對_a來說,d1和d2的_a都指向同一片空間,這就造成了在代碼結(jié)束時(shí),這片空間會釋放兩次,就會發(fā)生錯(cuò)誤,對此就需要進(jìn)行深拷貝來解決。
深拷貝
#include<iostream> using namespace std; class date { public: date(int b=1) { _a =new int[4]; _a[0] = 10; _b = b; } date(const date& d) { _a = new int[4]; memcpy(_a, d._a, sizeof(int) * 4);//將d2的數(shù)據(jù)拷貝過來 _b = d._b; } void print() { cout << _a[0] << ',' << _b << endl; } ~date() { free(_a); cout << "~date" << endl; } private: int* _a; int _b; }; int main() { date d1(5); date d2(d1); d2.print(); return 0; }
在拷貝構(gòu)造的時(shí)候?qū)Ρ绢惖腳a也進(jìn)行開辟空間,然后把另一類的數(shù)據(jù)利用memcpy拷貝過來就OK了。 這樣就不會出現(xiàn)析構(gòu)多次同一片空間的問題。
到此這篇關(guān)于C++ 拷貝構(gòu)造函數(shù)與賦值的區(qū)別的文章就介紹到這了,更多相關(guān)C++ 拷貝構(gòu)造函數(shù)與賦值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系
這篇文章主要介紹了C++中Cbitmap,HBitmap,Bitmap區(qū)別及聯(lián)系的相關(guān)資料,需要的朋友可以參考下2015-06-06簡要說明C語言中指針函數(shù)與函數(shù)指針的區(qū)別
這篇文章主要介紹了C語言中指針函數(shù)與函數(shù)指針的區(qū)別,指針函數(shù)和函數(shù)指針是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-04-04簡單掌握Linux系統(tǒng)中fork()函數(shù)創(chuàng)建子進(jìn)程的用法
fork()函數(shù)只能在類Unix系統(tǒng)下使用,因?yàn)樾枰雞nistd頭文件,這里我們就來簡單掌握Linux系統(tǒng)中fork()函數(shù)創(chuàng)建子進(jìn)程的用法,需要的朋友可以參考下2016-06-06基于C語言實(shí)現(xiàn)五子棋游戲完整實(shí)例代碼
這篇文章主要介紹了基于C語言實(shí)現(xiàn)五子棋游戲完整實(shí)例代碼,相信對于學(xué)習(xí)游戲開發(fā)的朋友會有一定的幫助與借鑒價(jià)值,需要的朋友可以參考下2014-08-08cocos2dx實(shí)現(xiàn)橡皮擦效果以及判斷是否擦除完畢
這篇文章主要為大家詳細(xì)介紹了cocos2dx實(shí)現(xiàn)橡皮擦效果以及判斷是否擦除完畢,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12一起來了解一下C++的結(jié)構(gòu)體?struct
這篇文章主要為大家詳細(xì)介紹了C++的結(jié)構(gòu)體struct,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02C語言中求余弦值的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語言中求余弦值的相關(guān)函數(shù)總結(jié),包括求余弦和雙曲線余弦以及反余弦的求值,需要的朋友可以參考下2015-08-08