真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

聊聊 C++ 中幾類特殊成員函數(shù)

一:背景

在 C# 中要說默認(rèn)給我們定義的特殊成員函數(shù),莫過于 構(gòu)造函數(shù),但在 C++ 中這樣的特殊函數(shù)高達(dá) 6 種,有必要整合一下聊一聊。

在長洲等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作專業(yè)公司,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),成都營銷網(wǎng)站建設(shè),外貿(mào)網(wǎng)站建設(shè),長洲網(wǎng)站建設(shè)費(fèi)用合理。

二:特殊成員函數(shù)

1. 默認(rèn)構(gòu)造函數(shù)

和 C# 一樣,很多書中都說,如果用戶沒有定義 構(gòu)造函數(shù),那么編譯器會給我們定義一個,參考下面的例子:


class Person {

public:
	string name;
	int age;
};

int main()
{
	Person person;
}

接下來觀察下匯編代碼,看下有沒有調(diào)用 默認(rèn)構(gòu)造函數(shù) .


	Person person;
003E32EF  lea         ecx,[person]  
003E32F2  call        Person::Person (03E15EBh)

對于 C# 學(xué)習(xí)者來說有點(diǎn)懵哈,定義了就相當(dāng)于new了, 哈哈,這是因?yàn)?C++ 默認(rèn)都是值類型哈,不過這里有必要澄清一下,并不一定所有情況都會調(diào)用 默認(rèn)構(gòu)造函數(shù),因?yàn)?C++ 的匯編生成由各自 編譯器 來決定,如果 編譯器 覺得沒必要調(diào)用 構(gòu)造函數(shù) 那它就會把這一步省掉來加速性能,那什么時候不會調(diào)呢? 參考如下代碼。


class Person {

public:
	void show() {
		printf("show!");
	}
};

int main()
{
	Person person;
	person.show();
}

接下來看下匯編代碼。


	person.show();
00E73F4F  lea         ecx,[person]  
00E73F52  call        Person::show (0E713B6h) 

可以清楚的看到,這種情況下調(diào)用 構(gòu)造函數(shù) 其實(shí)沒有必要,所以編譯器就干脆省略了。

2. 析構(gòu)函數(shù)

在 C# 中 析構(gòu)函數(shù) 是由 CLR 負(fù)責(zé)管理,在 C++ 中沒有托管這個概念,所以默認(rèn)只能是結(jié)束作用域之前,自動調(diào)用 析構(gòu)函數(shù) 釋放,參考如下圖:

3. 賦值構(gòu)造函數(shù)

剛才也說到了,在 C++ 中甭管是 class 還是 struct 默認(rèn)都是值類型,既然是值類型就存在stack copy 的情況,在 C# 中也是因?yàn)橹貙懥?EqualsGetHashCode 來實(shí)現(xiàn)的值copy,接下來簡單看下代碼:


class Person {

public:
	string name;
	int age;
};

int main()
{
	Person p1 = { "jack",20 };
	Person p2(p1);
}

再看下 Person p2(p1) 的匯編代碼。


	Person p2(p1);
000F80A2  lea         eax,[p1]  
000F80A5  push        eax  
000F80A6  lea         ecx,[p2]  
000F80A9  call        Person::Person (0F15C3h) 

從匯編中可以看到調(diào)用了 Person::Person (0F15C3h) 函數(shù),請注意,這個不是 構(gòu)造函數(shù),而是 賦值構(gòu)造函數(shù) ????, 可以調(diào)試下去看看哦。。。 截圖如下:

值得說一下的是,C++ 默認(rèn)提供的 賦值構(gòu)造函數(shù) 是淺copy,如果要實(shí)現(xiàn)深 copy 的話,或者有一些自定義的邏輯,建議自己實(shí)現(xiàn)一下。


class Person {

public:
	string name;
	int age;

public:
	Person(string name, int age) :name(name), age(age) {}
	Person(const Person& p) {
		name = p.name;
		age = p.age;
	}
};

int main()
{
	Person p1 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaa",20 };
	Person p2(p1);
}

4. 賦值運(yùn)算符

在 C# 中 值類型, 匿名類型, Record 都是重寫過 Equals= 運(yùn)算符,所以可以在這些類型上用 =, 其實(shí)在 C++ 中也可以在 class 之間進(jìn)行賦值,因?yàn)榫幾g器會幫我們重寫運(yùn)算符 = ,如何看出來呢?先看下代碼:


class Person {

public:
	string name;
	int age;

public:
	Person(string name, int age) :name(name), age(age) {}
	Person(const Person& p) {
		name = p.name;
		age = p.age;
	}
};

int main()
{
	Person p1 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaa",20 };
	Person p2 = { "bbbbbbbbbbbbbbbbbbbbbbbbbbb",22 };

	p2 = p1;
}

最后一句的 p2 = p1 之所以能成功是因?yàn)?= 被重寫了,參考匯編代碼。


	p2 = p1;
00FD967C  lea         eax,[p1]  
00FD967F  push        eax  
00FD9680  lea         ecx,[p2]  
00FD9683  call        Person::operator= (0FD161Dh)  

如果需要自定義,可以自己重寫。


class Person {

public:
	string name;
	int age;

public:
	Person(string name, int age) :name(name), age(age) {}
	Person(const Person& p) {
		name = p.name;
		age = p.age;
	}
	Person& operator = (const Person& p) {
		name = p.name;
		age = p.age;
		return *this;
	}
};

int main()
{
	Person p1 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaa",20 };
	Person p2 = { "bbbbbbbbbbbbbbbbbbbbbbbbbbb",22 };

	p2 = p1;
}

在 C++ 11 中還有特殊的 移動構(gòu)造函數(shù)移動賦值構(gòu)造函數(shù), 這個還需要理解 左值 和 右值引用,篇幅有限,放到后面和大家聊了哈。


當(dāng)前標(biāo)題:聊聊 C++ 中幾類特殊成員函數(shù)
分享地址:http://weahome.cn/article/dsoijdj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部