對比 C# 聊聊 C++ 中幾類特殊成員函數

一:背景

在 C# 中要說默認給我們定義的特殊成員函數,莫過于 構造函數,但在 C++ 中這樣的特殊函數高達 6 種,有必要整合一下聊一聊。

二:特殊成員函數

1. 默認構造函數

和 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)

可以清楚的看到,這種情況下調用 構造函數 ?其實沒有必要,所以編譯器就干脆省略了。

2. 析構函數

在 C# 中 析構函數 是由 CLR 負責管理,在 C++ 中沒有托管這個概念,所以默認只能是結束作用域之前,自動調用 析構函數 釋放,參考如下圖:

a714cfdbb32b43a5735ad01e9bef711b.png

3. 賦值構造函數

剛才也說到了,在 C++ 中甭管是 class 還是 struct 默認都是值類型,既然是值類型就存在stack copy 的情況,在 C# 中也是因為重寫了 EqualsGetHashCode 來實現的值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) 函數,請注意,這個不是 構造函數,而是 賦值構造函數 😂, 可以調試下去看看哦。。。截圖如下:

ac58633bdb063a0d016dfff6939ecc05.png

值得說一下的是,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);
}

4. 賦值運算符

在 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)
4fc0294d477cf30bdef415683ee215e7.png

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

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 中還有特殊的 移動構造函數移動賦值構造函數, 這個還需要理解 左值 和 右值引用,篇幅有限,放到后面和大家聊了哈。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284927.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284927.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284927.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Js 枚舉定義Layer Icon

layer的icon有7種樣式:1-7 [圖片來自:https://blog.csdn.net/beauxie/article/details/60959971] 有時候常常記不住 😣,不防自己定義一哈: var layerIcon {//無none: -1,//成功success: 1,//失敗error: 2,//提問、疑…

前端進階之路: 前端架構設計(2)-流程核心

可能很多人和我一樣, 首次聽到"前端架構"這個詞, 第一反應是: "前端還有架構這一說呢?" 在后端開發領域, 系統規劃和可擴展性非常關鍵, 因此架構師備受重視, 早在開發工作啟動之前, 他們就被邀請加入到項目中, 而且他們會跟客戶討論即將建成的平臺的架構要…

C語言試題195之實現strnchr函數功能

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目: 實現strnchr函數功能 函數名稱:在字符串中查找字符 函數原型:char *strnchr(cons…

8.2設備文件及磁盤分區

2019獨角獸企業重金招聘Python工程師標準>>> 概覽: 設備文件的創建 權限 設備名 類型 主設備號 次設備號 mknod [-m MODE] NAME type [MAJOR MINOR] 創建時,先查看是否存在設備號的沖突 零磁道零扇區是MBR:Maste…

【ArcGIS風暴】ArcGIS求一個矢量圖層中多個圖斑的“四至點”坐標案例教程

如圖所示,為ArcGIS軟件自帶的全球矢量數據,怎樣求取每個大洲(圖斑)的四至坐標(xmin、ymin、xmax、ymax)呢? 參考閱讀:【ArcGIS遇上Python】python批量獲取柵格數據四至(top,bottom,left,right)坐標代碼 文章目錄 1. 矢量數據加載2. 四至計算結果3. 四至計算過程1.…

一個關于導出excel模板的實例

1 首先jsp頁面 點擊模板下載&#xff0c;會自動下載模板&#xff45;&#xff58;&#xff43;&#xff45;&#xff4c;&#xff0c;效果如下 讓我們看源碼&#xff1a; &#xff11; &#xff4a;&#xff53;&#xff50;頁面 <div class"tab-pane" id"p…

騰訊視頻VIP會員,周卡特價9.5元!

今天給大家推薦特價充值騰訊視頻VIP會員的平臺——幻海優品&#xff0c;騰訊視頻在線直充&#xff0c;VIP會員實時生效&#xff01;騰訊視頻VIP會員特價充值周卡&#xff1a;原價12元&#xff0c;特價9.5元月卡&#xff1a;原價30元&#xff0c;特價22元季卡&#xff1a;原價68…

解決安裝SQL Server 2005開發版時,出現“SQL Server 服務無法啟動 ”點擊重試或取消的解決方法

問題描述&#xff1a; 安裝SQL Server 2005開發版時&#xff0c;提示SQL Server服務無法啟動&#xff0c;有關詳細信息&#xff0c;請參閱SQL Server聯機叢書中的主題如何查看SQL Server 2005安裝日志文件和手動啟動SQL Server&#xff0c;如下圖所示。 此時&#xff0c;如果點…

C語言試題196之實現strstr函數功能

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目: 實現strstr函數功能 C 庫函數 char *strstr(const char *haystack, const char *nee…

svnsync實現版本庫的同步備份

svnsync實現版本庫的同步備份 實驗環境&#xff1a;A&#xff0c;172.17.201.243&#xff08;主&#xff09;B&#xff0c;172.17.201.88&#xff08;備&#xff09;項目需求&#xff0c;生產環境要求svn服務器實現熱備機制&#xff0c;于是就想到了svn自帶的svnsync機制&#…

關于數據結構(二)

文章目錄[點擊展開](?)[] 一UI返回功能思路分析實現方法二當前正在CD技能接著上文<<關于數據結構(一)>>&#xff0c;關于數據結構&#xff0c;在實際的開發中或多或少都有涉及到&#xff0c;只是看自己平時沒有積累到。下面是我在項目中的幾個實例&#xff1a; 一…

JDBC 之 事務

1.概念&#xff1a;事務指邏輯上的一組操作&#xff0c;組成這組操作的各個單元&#xff0c;要么全部成功&#xff0c;要么全部不成功。 2.數據庫開啟事務的命令dtl&#xff1a; Start transaction開啟事務 Rollback回滾事務&#xff08;撤銷&#xff09; Commit提交事務 3.JDB…

[轉]后端程序員必備:書寫高質量SQL的30條建議

以下文章來源于撿田螺的小男孩 &#xff0c;作者撿田螺的小男孩 轉載&#xff1a;《后端程序員必備&#xff1a;書寫高質量SQL的30條建議》 前言 本文將結合實例demo&#xff0c;闡述30條有關于優化SQL的建議&#xff0c;多數是實際開發中總結出來的&#xff0c;希望對大家有…

GIS熱詞:AR、VR、MR辨析

AR、VR、MR技術讓我們見識到了科技神奇的同時&#xff0c;也讓真實可感的現實世界和無法觸摸的虛擬世界的聯系更加緊密。 1. AR AR&#xff0c;全稱Augmented Reality&#xff0c;即增強現實技術。這項技術是利用電腦技術將虛擬的信息疊加到真實世界&#xff0c;通過手機、平板…

云原生數據庫是未來數據庫的天下

一、傳統數據庫的發展階段和痛點 1&#xff09;、傳統數據庫的發展階段 ?人工管理階段 20世紀50十年代中期以前&#xff0c;計算機只是用來計算的&#xff0c;那么數據管理就只能純人工. ?文件系統管理階段 20世紀50年代后期到60年代中期&#xff0c;這時硬件方面有了磁盤、磁…

用.NET做DDNS動態域名解析和SSL證書申請

本文主要介紹 IPv6 配置 DDNS 解析和 SSL 證書申請工具的開發歷程和其中的相關知識。工具使用.NET開發&#xff0c;已開源&#xff0c;目前該工具的域名解析只支持阿里云。文中提及或使用的 .NET 開源項目&#xff1a;SangServerTool&#xff08;DDNS,SSL證書申請工具&#xff…

匯編學習(一)

看的是王爽老師的《匯編語言》第三版基礎知識 一.匯編語言的誕生上古時期在匯編語言還未出現的時候&#xff0c;那時的程序員還只能用二進制也就是所謂的機器語言寫代碼&#xff0c;將0和1編成的程序代碼打在紙帶或卡片上&#xff0c;再將紙帶卡片輸入計算機&#xff0c;進行運…

Java 網絡編程1

talnet工具與Socket類 如今單機的程序已經不太能適合用戶的需要&#xff0c;網絡編程變得比以往更加重要。首先需要認識一下talnet工具&#xff0c;可以使用該工具來連接服務器在終端中輸入,可以進入本地的80端口 talnet 127.0.0.1 80 需要我們輸入ip地址和端口號&#xff0c;使…

【GIS風暴】GeoJSON數據格式案例全解

在了解GeoJSON數據之前,先來通過一個網站和一個簡單的代碼案例,看一下GeoJSON的神奇魅力吧! 網站:http://geojson.io 打開上述網站,在左側的代碼區域粘入中國區域GeoJSON代碼,如下所示: 中國地圖: 地名:

mysqldump參數大全

參數 參數說明 --all-databases , -A 導出全部數據庫。 mysqldump -uroot -p --all-databases --all-tablespaces , -Y 導出全部表空間。 mysqldump -uroot -p --all-databases --all-tablespaces --no-tablespaces , -y 不導出任何表空間信息。 mysqldump -uroot -p --a…