在 C# 中要說類
預設給我們定義的特殊成員函數,莫過於 建構函式
,但在 C++ 中這樣的特殊函數高達 6 種,有必要整合一下聊一聊。
和 C# 一樣,很多書中都說,如果使用者沒有定義 建構函式
,那麼編譯器會給我們定義一個,參考下面的例子:
class Person {
public:
string name;
int age;
};
int main()
{
Person person;
}
接下來觀察下組合程式碼,看下有沒有呼叫 預設建構函式
.
Person person;
003E32EF lea ecx,[person]
003E32F2 call Person::Person (03E15EBh)
對於 C# 學習者來說有點懵哈,定義了就相當於new了, 哈哈,這是因為 C++ 預設都是值型別哈,不過這裡有必要澄清一下,並不一定所有情況都會呼叫 預設建構函式
,因為 C++ 的組合生成由各自 編譯器 來決定,如果 編譯器
覺得沒必要呼叫 建構函式
那它就會把這一步省掉來加速效能,那什麼時候不會調呢? 參考如下程式碼。
class Person {
public:
void show() {
printf("show!");
}
};
int main()
{
Person person;
person.show();
}
接下來看下組合程式碼。
person.show();
00E73F4F lea ecx,[person]
00E73F52 call Person::show (0E713B6h)
可以清楚的看到,這種情況下呼叫 建構函式
其實沒有必要,所以編譯器就乾脆省略了。
在 C# 中 解構函式
是由 CLR 負責管理,在 C++ 中沒有託管這個概念,所以預設只能是結束作用域之前,自動呼叫 解構函式
釋放,參考如下圖:
剛才也說到了,在 C++ 中甭管是 class 還是 struct 預設都是值型別,既然是值型別就存在stack copy
的情況,在 C# 中也是因為重寫了 Equals
和 GetHashCode
來實現的值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)
從組合中可以看到呼叫了 Person::Person (0F15C3h)
函數,請注意,這個不是 建構函式
,而是 賦值建構函式