<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在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)
函數,請注意,這個不是建構函式,而是 賦值建構函式, 可以偵錯下去看看哦。。。 截圖如下:
值得說一下的是,C++ 預設提供的賦值建構函式是淺copy,如果要實現深 copy 的話,或者有一些自定義的邏輯,建議自己實現一下。
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); }
在 C# 中值型別, 匿名型別, Record
都是重寫過 Equals
及 =
運運算元,所以可以在這些型別上用 =
, 其實在 C++ 中也可以在 class 之間進行賦值,因為編譯器會幫我們重寫運運算元 =
,如何看出來呢?先看下程式碼:
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
之所以能成功是因為 =
被重寫了,參考組合程式碼。
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++中的特殊成員函數的文章就介紹到這了,更多相關C++ 特殊成員函數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45