日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網(wǎng)站首頁 編程語言 正文

C++的拷貝構(gòu)造函數(shù)你了解嗎_C 語言

作者:Kallou ? 更新時間: 2022-05-22 編程語言

拷貝構(gòu)造函數(shù)用以將一個類的對象拷貝給同一個類的另一個對象,比如之前學習過的string類:

string s1;
string s2 = s1;

一般情況下的拷貝構(gòu)造函數(shù):

class A
{
private:
	int n;
	double d;
	char s;
public:
	A(const A& a);
};
A::A(const A& a)
{
	this->n = a.n;
	this->d = a.d;
	this->s = a.s;
}

即按照數(shù)據(jù)類型開辟一段內(nèi)存空間用以存放拷貝進來的對象的數(shù)據(jù)。需要注意的是必須傳遞進來的是類的引用,如果是按值傳遞,將會生成一個臨時的類的對象a,并將傳遞進來對象拷貝給臨時對象,其實就是又調(diào)用了拷貝構(gòu)造函數(shù)。

默認拷貝構(gòu)造函數(shù):

如果用戶沒有自定義拷貝構(gòu)造函數(shù),又使用了對象的拷貝,則編譯器會自動生成一個默認構(gòu)造函數(shù),格式同上。

淺拷貝和深拷貝:

大多數(shù)情況下,使用默認構(gòu)造函數(shù)就可以完成對象的拷貝(淺拷貝),但是當對象中有諸如指針、動態(tài)數(shù)組等數(shù)據(jù)類型時使用默認構(gòu)造函數(shù)則可能出錯,此時需要用戶自定義拷貝構(gòu)造函數(shù)(深拷貝),以下是一個例子,首先是沒有自定義拷貝構(gòu)造函數(shù)的情況:

class A
{
private:
	char* str;
	int len;
public:
	A(const char* s);
	~A();
	//A(const A& a);
};
A::A(const char* s)
{
	len = strlen(s);
	str = new char[len+1];
	strcpy(str, s);
	cout << str << " object construct." << endl;
}
A::~A()
{
	cout << str << " deleted." << endl;
	delete[]str;
}
//A::A(const A& a)
//{
//	this->len = a.len;
//	this->str = new char[a.len+1];
//	strcpy(str, a.str);
//}

調(diào)用函數(shù):

int main(void)
{
	A a1("Hello");
	A a2 = a1;
	return 0;
}

運行結(jié)果:

Hello object construct.
Hello deleted.
葺葺葺葺葺葺葺葺攐? deleted.

這是因為在對象復制的時候,由于編譯器生成了默認拷貝構(gòu)造函數(shù),只是單純的將a1中指針str的值賦值給a2中的指針str,導致a2的生命周期結(jié)束時調(diào)用析構(gòu)函數(shù)將str指向的內(nèi)存空間內(nèi)容釋放掉了,于是a1生命周期結(jié)束時調(diào)用析構(gòu)函數(shù)釋放掉的內(nèi)存中的內(nèi)容就是無意義的字符了。

去掉注釋后的正確寫法:

class A
{
private:
	char* str;
	int len;
public:
	A(const char* s);
	~A();
	A(const A& a);
};
A::A(const char* s)
{
	len = strlen(s);
	str = new char[len+1];
	strcpy(str, s);
	cout << str << " object construct." << endl;
}
A::~A()
{
	cout << str << " deleted." << endl;
	delete[]str;
}
A::A(const A& a)
{
	this->len = a.len;
	this->str = new char[a.len+1];
	strcpy(str, a.str);
}

調(diào)用函數(shù)同上。

運行結(jié)果:

Hello object construct.
Hello deleted.
Hello deleted.

這里自定義了拷貝構(gòu)造函數(shù),申請了一塊新的內(nèi)存空間來存放拷貝進來的字符串,因此釋放時就不會出錯了。

總結(jié)

原文鏈接:https://blog.csdn.net/Kallou/article/details/123602916

欄目分類
最近更新