C++?拷貝構(gòu)造函數(shù)與賦值的區(qū)別
拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)的也是一種構(gòu)造函數(shù),它的作用是將一個類的成員拷貝到另一個類中,類似于賦值。拷貝構(gòu)造函數(shù)分為深拷貝和淺拷貝。
先來定義一個拷貝構(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;
};將一個類拷貝到另一個類中,自然是需要對應(yīng)的參數(shù)的,參數(shù)就是類,這里可以傳遞指針,引用更好,只是傳值形參的話,會造成無限遞歸。
拷貝構(gòu)造函數(shù)的使用方法
拷貝構(gòu)造函數(shù)的使用:
1.使用();2.使用'=';像這樣

拷貝構(gòu)造函數(shù)與賦值運算符的區(qū)別
那么拷貝構(gòu)造函數(shù)和賦值運算符有什么區(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)造變量時就對類進(jìn)行了賦值,這個賦值叫做初始化,而后者是先定義好的類,后續(xù)賦值,在賦值之前是已經(jīng)將變量創(chuàng)建好的;
談深拷貝和淺拷貝
先說淺拷貝
淺拷貝
淺拷貝就是對成員變量進(jìn)行一一對應(yīng)賦值,來看一個代碼:
#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;
}在這個代碼中,在對d2進(jìn)行初始化的時候,是將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ò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é)束時,這片空間會釋放兩次,就會發(fā)生錯誤,對此就需要進(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)造的時候?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)下使用,因為需要引入unistd頭文件,這里我們就來簡單掌握Linux系統(tǒng)中fork()函數(shù)創(chuàng)建子進(jìn)程的用法,需要的朋友可以參考下2016-06-06
cocos2dx實現(xiàn)橡皮擦效果以及判斷是否擦除完畢
這篇文章主要為大家詳細(xì)介紹了cocos2dx實現(xiàn)橡皮擦效果以及判斷是否擦除完畢,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12
一起來了解一下C++的結(jié)構(gòu)體?struct
這篇文章主要為大家詳細(xì)介紹了C++的結(jié)構(gòu)體struct,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02
C語言中求余弦值的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語言中求余弦值的相關(guān)函數(shù)總結(jié),包括求余弦和雙曲線余弦以及反余弦的求值,需要的朋友可以參考下2015-08-08

