一起聊聊C++中的特殊成員函數(shù)
一:背景
在C#中要說(shuō)類(lèi)默認(rèn)給我們定義的特殊成員函數(shù),莫過(guò)于構(gòu)造函數(shù),但在 C++ 中這樣的特殊函數(shù)高達(dá) 6 種,有必要整合一下聊一聊。
二:特殊成員函數(shù)
1. 默認(rèn)構(gòu)造函數(shù)
和 C# 一樣,很多書(shū)中都說(shuō),如果用戶(hù)沒(méi)有定義 構(gòu)造函數(shù),那么編譯器會(huì)給我們定義一個(gè),參考下面的例子:
class Person {
public:
string name;
int age;
};
int main()
{
Person person;
}
接下來(lái)觀察下匯編代碼,看下有沒(méi)有調(diào)用 默認(rèn)構(gòu)造函數(shù) .
Person person;
003E32EF lea ecx,[person]
003E32F2 call Person::Person (03E15EBh)
對(duì)于 C# 學(xué)習(xí)者來(lái)說(shuō)有點(diǎn)懵哈,定義了就相當(dāng)于new了, 哈哈,這是因?yàn)镃++默認(rèn)都是值類(lèi)型哈,不過(guò)這里有必要澄清一下,并不一定所有情況都會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù),因?yàn)镃++的匯編生成由各自 編譯器 來(lái)決定,如果 編譯器 覺(jué)得沒(méi)必要調(diào)用構(gòu)造函數(shù) 那它就會(huì)把這一步省掉來(lái)加速性能,那什么時(shí)候不會(huì)調(diào)呢? 參考如下代碼。
class Person {
public:
void show() {
printf("show!");
}
};
int main()
{
Person person;
person.show();
}接下來(lái)看下匯編代碼。
person.show();
00E73F4F lea ecx,[person]
00E73F52 call Person::show (0E713B6h)
可以清楚的看到,這種情況下調(diào)用構(gòu)造函數(shù)其實(shí)沒(méi)有必要,所以編譯器就干脆省略了。
2. 析構(gòu)函數(shù)
在C#中析構(gòu)函數(shù) 是由CLR負(fù)責(zé)管理,在C++中沒(méi)有托管這個(gè)概念,所以默認(rèn)只能是結(jié)束作用域之前,自動(dòng)調(diào)用析構(gòu)函數(shù)釋放,參考如下圖:

3. 賦值構(gòu)造函數(shù)
剛才也說(shuō)到了,在 C++ 中甭管是 class 還是 struct 默認(rèn)都是值類(lèi)型,既然是值類(lèi)型就存在stack copy 的情況,在 C# 中也是因?yàn)橹貙?xiě)了 Equals 和 GetHashCode 來(lái)實(shí)現(xiàn)的值copy,接下來(lái)簡(jiǎn)單看下代碼:
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ù),請(qǐng)注意,這個(gè)不是構(gòu)造函數(shù),而是 賦值構(gòu)造函數(shù), 可以調(diào)試下去看看哦。。。 截圖如下:

值得說(shuō)一下的是,C++ 默認(rèn)提供的賦值構(gòu)造函數(shù)是淺copy,如果要實(shí)現(xiàn)深 copy 的話(huà),或者有一些自定義的邏輯,建議自己實(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# 中值類(lèi)型, 匿名類(lèi)型, Record 都是重寫(xiě)過(guò) Equals 及 = 運(yùn)算符,所以可以在這些類(lèi)型上用 =, 其實(shí)在 C++ 中也可以在 class 之間進(jìn)行賦值,因?yàn)榫幾g器會(huì)幫我們重寫(xiě)運(yùn)算符 = ,如何看出來(lái)呢?先看下代碼:
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)?nbsp;= 被重寫(xiě)了,參考匯編代碼。
p2 = p1;
00FD967C lea eax,[p1]
00FD967F push eax
00FD9680 lea ecx,[p2]
00FD9683 call Person::operator= (0FD161Dh)

如果需要自定義,可以自己重寫(xiě)。
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;
}到此這篇關(guān)于一起聊聊C++中的特殊成員函數(shù)的文章就介紹到這了,更多相關(guān)C++ 特殊成員函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)BMP圖像細(xì)化處理
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)BMP圖像細(xì)化處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
C++棧(stack)的模板類(lèi)實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了C++棧(stack)的模板類(lèi)實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
異步http listener 完全并發(fā)處理懲罰http懇求的小例子
異步http listener 完全并發(fā)處理懲罰http懇求的小例子,需要的朋友可以參考一下2013-05-05
詳解C++類(lèi)的成員函數(shù)做友元產(chǎn)生的循環(huán)依賴(lài)問(wèn)題
這篇文章主要為大家詳細(xì)介紹了C++類(lèi)的成員函數(shù)做友元產(chǎn)生的循環(huán)依賴(lài)問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03
使用C語(yǔ)言實(shí)現(xiàn)從avi視頻中提取圖片
這篇文章主要為大家詳細(xì)介紹了如何使用C語(yǔ)言實(shí)現(xiàn)從avi視頻中提取圖片,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2023-10-10
C++?vector與數(shù)組轉(zhuǎn)換寫(xiě)入/讀出文件方式
這篇文章主要介紹了C++?vector與數(shù)組轉(zhuǎn)換寫(xiě)入/讀出文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11

