C++中explicit詳解

文章目錄

      • 1. **防止隱式類型轉換**
        • 示例1:沒有使用`explicit`
        • 示例2:使用`explicit`
      • 2. **防止拷貝初始化**
        • 示例1:沒有使用`explicit`
        • 示例2:使用`explicit`
      • 3. **防止隱式類型轉換的鏈式調用**
        • 示例1:沒有使用`explicit`
        • 示例2:使用`explicit`
      • 4. **防止隱式類型轉換的歧義**
        • 示例1:沒有使用`explicit`
        • 示例2:使用`explicit`
      • 總結

在C++中, explicit關鍵字用于修飾構造函數和轉換運算符,其主要目的是防止隱式類型轉換和拷貝初始化,從而提高代碼的可讀性和安全性。以下是 explicit的詳細作用和使用場景:

1. 防止隱式類型轉換

當構造函數被聲明為explicit時,它不能用于隱式類型轉換。這意味著不能通過單個參數的構造函數隱式地將一個類型轉換為另一個類型。

示例1:沒有使用explicit
class MyClass {
public:MyClass(int x) : value(x) {} // 非explicit構造函數int value;
};void printMyClass(MyClass obj) {std::cout << obj.value << std::endl;
}int main() {printMyClass(10); // 隱式調用 MyClass(int) 構造函數return 0;
}

在這個例子中,MyClass(int)構造函數是非explicit的,因此可以隱式地將int類型轉換為MyClass類型。調用printMyClass(10)時,會隱式地調用MyClass(10)構造函數。

示例2:使用explicit
class MyClass {
public:explicit MyClass(int x) : value(x) {} // explicit構造函數int value;
};void printMyClass(MyClass obj) {std::cout << obj.value << std::endl;
}int main() {// printMyClass(10); // 錯誤:無法隱式調用 MyClass(int) 構造函數printMyClass(MyClass(10)); // 顯式調用 MyClass(10) 構造函數return 0;
}

在這個例子中,MyClass(int)構造函數被聲明為explicit,因此不能隱式地將int類型轉換為MyClass類型。調用printMyClass(10)時,會報錯,必須顯式地調用MyClass(10)構造函數。

2. 防止拷貝初始化

explicit構造函數不能用于拷貝初始化,但可以用于直接初始化。

示例1:沒有使用explicit
class MyClass {
public:MyClass(int x) : value(x) {} // 非explicit構造函數int value;
};int main() {MyClass obj = 10; // 拷貝初始化,隱式調用 MyClass(int) 構造函數return 0;
}

在這個例子中,MyClass(int)構造函數是非explicit的,因此可以用于拷貝初始化。

示例2:使用explicit
class MyClass {
public:explicit MyClass(int x) : value(x) {} // explicit構造函數int value;
};int main() {// MyClass obj = 10; // 錯誤:無法隱式調用 MyClass(int) 構造函數MyClass obj(10); // 直接初始化,顯式調用 MyClass(int) 構造函數return 0;
}

在這個例子中,MyClass(int)構造函數被聲明為explicit,因此不能用于拷貝初始化。必須使用直接初始化的方式顯式調用構造函數。

3. 防止隱式類型轉換的鏈式調用

explicit可以防止多個隱式類型轉換的鏈式調用,從而避免潛在的錯誤。

示例1:沒有使用explicit
class MyClass {
public:MyClass(int x) : value(x) {} // 非explicit構造函數int value;
};class YourClass {
public:YourClass(MyClass obj) : myObj(obj) {} // 非explicit構造函數MyClass myObj;
};int main() {YourClass obj = 10; // 隱式調用 MyClass(int) 和 YourClass(MyClass)return 0;
}

在這個例子中,MyClass(int)YourClass(MyClass)構造函數都是非explicit的,因此可以隱式地將int類型轉換為MyClass類型,再將MyClass類型轉換為YourClass類型。

示例2:使用explicit
class MyClass {
public:explicit MyClass(int x) : value(x) {} // explicit構造函數int value;
};class YourClass {
public:explicit YourClass(MyClass obj) : myObj(obj) {} // explicit構造函數MyClass myObj;
};int main() {// YourClass obj = 10; // 錯誤:無法隱式調用 MyClass(int) 和 YourClass(MyClass)YourClass obj(MyClass(10)); // 顯式調用 MyClass(10) 和 YourClass(MyClass)return 0;
}

在這個例子中,MyClass(int)YourClass(MyClass)構造函數都被聲明為explicit,因此不能隱式地進行類型轉換。必須顯式地調用構造函數。

4. 防止隱式類型轉換的歧義

在某些情況下,多個構造函數可能導致隱式類型轉換的歧義。使用explicit可以避免這種歧義。

示例1:沒有使用explicit
class MyClass {
public:MyClass(int x) : value(x) {} // 非explicit構造函數MyClass(double x) : value(static_cast<int>(x)) {} // 非explicit構造函數int value;
};void printMyClass(MyClass obj) {std::cout << obj.value << std::endl;
}int main() {printMyClass(10); // 隱式調用 MyClass(int) 構造函數printMyClass(10.5); // 隱式調用 MyClass(double) 構造函數return 0;
}

在這個例子中,MyClass(int)MyClass(double)構造函數都是非explicit的,因此可以隱式地將intdouble類型轉換為MyClass類型。

示例2:使用explicit
class MyClass {
public:explicit MyClass(int x) : value(x) {} // explicit構造函數explicit MyClass(double x) : value(static_cast<int>(x)) {} // explicit構造函數int value;
};void printMyClass(MyClass obj) {std::cout << obj.value << std::endl;
}int main() {// printMyClass(10); // 錯誤:無法隱式調用 MyClass(int) 構造函數// printMyClass(10.5); // 錯誤:無法隱式調用 MyClass(double) 構造函數printMyClass(MyClass(10)); // 顯式調用 MyClass(int) 構造函數printMyClass(MyClass(10.5)); // 顯式調用 MyClass(double) 構造函數return 0;
}

在這個例子中,MyClass(int)MyClass(double)構造函數都被聲明為explicit,因此不能隱式地進行類型轉換。必須顯式地調用構造函數,避免了潛在的歧義。

總結

explicit關鍵字的主要作用是防止隱式類型轉換和拷貝初始化,從而提高代碼的可讀性和安全性。在設計類時,如果某個構造函數或轉換運算符不應該被隱式調用,應該使用explicit關鍵字進行修飾。

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

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

相關文章

代碼部落 20250629 CSP-J復賽 模擬賽

網址&#xff1a;代碼部落 一&#xff1a; 相濡以沫 β&#xff08;代碼請自寫&#xff09; 簽到題&#xff0c;如果a[i]<a[i1] a[i]a[i1],反之&#xff0c;直接輸出No 二 共同富裕&#xff08;代碼請自寫&#xff09; 簽到題&#xff0c;用sort前綴和 如果最富有的個…

零基礎學習RabbitMQ(5)--工作模式(1)

在前面的章節中我們簡單介紹過一些RabbitMQ的工作模式&#xff0c;RabbitMQ共提供了七種工作模式進行消息傳遞&#xff0c;這里我們來詳細介紹。 1. Simple(簡單模式) P&#xff1a;生產者 C&#xff1a;消費者 特點&#xff1a;一個生產者一個消費者&#xff0c;消息只能被…

Android Liunx ffmpeg交叉編譯

本文的交叉編譯在window上安裝VMware&#xff0c;使用Ubuntu20.4進行的編譯。 一、安裝NDK&#xff1a; 1、下載解壓&#xff1a; 在NDK 下載 | Android NDK | Android Developers下載Liunx平臺的NDK。 本人下載的是android-ndk-r27c-linux.zip版本的。 解壓android-ndk-r…

極海G32R501雙向數字電源解決方案 賦能AI服務器及電源應用創新

6月26日&#xff0c;Big-Bit商務網主辦的2025中國電子熱點解決方案創新峰會在東莞召開&#xff0c;峰會以“核心智變、能效躍遷”為主題&#xff0c;聚焦光儲充、800V超充、AI服務器、BMS、智能汽車照明與汽車中小電機電控應用。 峰會期間&#xff0c;珠海極海半導體有限公司&a…

【修電腦的小記錄】連不上網

問題概述 問題表現為&#xff1a;電腦連接網絡后&#xff0c;顯示已連接但無法上網。 環境信息&#xff1a; - DNS 修改無效&#xff0c;ping 外網&#xff08;8.8.8.8&#xff09;失敗 - 嘗試重置網絡參數、多種命令無果 &#x1f50d; 排查過程 1. 執行以下命令重置網絡&a…

QT中QSS樣式表的詳細介紹

轉自個人博客 **Qt樣式表&#xff08;Qt Style Sheets&#xff0c;簡稱QSS&#xff09;**是一種類似于HTML中的CSS&#xff08;層疊樣式表&#xff09;的機制&#xff0c;用于自定義Qt應用程序的外觀。通過QSS&#xff0c;開發者可以輕松地修改控件的外觀&#xff0c;而無需更改…

Spring 依賴注入:官方推薦方式及最佳實踐

Spring 依賴注入&#xff1a;官方推薦方式及最佳實踐 你正在遭遇以下困境嗎&#xff1f; 項目變大后&#xff0c;依賴關系像一團亂麻&#xff0c;牽一發而動全身&#xff1f;單元測試難如登天&#xff0c;被迫啟動整個Spring容器&#xff1f;NullPointerException 總在運行時突…

javaweb聽課筆記day1

MySQL數據模型 關系型數據庫: 通過表來存儲數據 關系型數據庫是建立在關系模型基礎上的數據庫&#xff0c;簡單說&#xff0c;關系型數據庫是由多張能互相連接的二維表組成的數據庫 優點: 都是使用表結構&#xff0c;格式一致&#xff0c;易于維護;使用通用的SQL語言操作…

《從量子奇境到前端優化:解鎖卡西米爾效應的隱藏力量》

卡西米爾效應由荷蘭物理學家亨德里克卡西米爾于1948年提出&#xff0c;它源于量子場論中“真空不空”的奇異觀點。在傳統認知里&#xff0c;真空是一片虛無&#xff0c;但量子理論指出&#xff0c;真空中充滿了持續漲落的能量&#xff0c;即零點能。想象有兩片中性的金屬板被放…

【學習筆記】強化學習的數學原理

軟活硬整&#xff0c;納什又把RL翻出來講了一遍&#xff0c;我以為是溫故而知新&#xff0c;原來是在賣書。 不過溫故而知新還是沒啥毛病的。 PS&#xff1a;今天裝Notepad時看到的&#xff0c;我還以為現在連用個Notepad都要給天線寶寶們捐款了。 文章目錄 PART 11 overview…

深入“火星棒球數據API”:用數據解鎖棒球世界的無限可能

在棒球運動日益數據化的今天&#xff0c;高效獲取和處理海量比賽信息已成為球隊制勝、媒體解讀、球迷深入理解比賽的關鍵。“火星棒球數據API” 應運而生&#xff0c;成為連接棒球智慧與大數據技術的橋梁。本文將探討這一API的核心價值、功能亮點及其如何重塑我們體驗和分析棒球…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+jsp實現的校園服務平臺管理系統,推薦!

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本校園服務平臺管理系統就是在這樣的大環境下誕生&#xff0c;其可以幫助管理者在短時間內處理完畢龐大的數據…

「Java EE開發指南」如何用MyEclipse創建一個WEB項目?(三)

在本文中&#xff0c;您可以找到有關WEB項目的信息。將了解&#xff1a; Web項目結構和參數Web開發生產力工具JSP代碼完成和驗證 這些特性在MyEclipse中可用。在上文中&#xff08;點擊這里回顧>>&#xff09;&#xff0c;我們為大家介紹了Web開發效率工具、Web項目參數…

笨方法學python -練習6

程序&#xff1a; print("Mary had a little lamb.") print("Its fleece was white as {}.".format(snow)) print("And everywhere that Mary went.") print("." * 10) # what′d that do? end1 "C" end2 "h&qu…

【MySQL】Binlog文件占用空間比較大,如何清理

一、前言 在進行一次數據導入之后&#xff0c;發現服務器磁盤爆滿&#xff0c;初步判斷是數據庫產生了大量binlog所致&#xff0c;接下來進行分析處理。 二、分析 1、查看磁盤空間 通過df -h命令&#xff0c;查看磁盤空間占用情況 2、查找占用文件或目錄 通過命令&#xff1a;…

車載診斷架構 --- 非易失性存儲器(NVM)相關設置項

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

C#: 輸入對話框窗口函數

這是一個 C# 輸入對話框函數&#xff0c;主要功能包括&#xff1a; 基礎功能&#xff1a;創建帶標題、提示文本和輸入框的對話框&#xff0c;返回用戶輸入或空字符串&#xff08;取消時&#xff09; 增強特性&#xff1a; 支持必填項驗證支持正則表達式格式驗證實時錯誤提示與…

PCB工藝學習與總結-20250628

一、PCB板材 1、結構組成 基板:作為電路板的支撐體,通常由絕緣材料制成,如玻璃纖維或塑料。 導線:用于連接電路板上的各個元件,傳輸電流和信號。 元件:包括電阻、電容、電感、二極管、晶體管等,用于實現電路的各種功能。 焊盤:用于焊接元件引腳的金屬片,確保元件…

VUE2與VUE3項目環境變量創建與使用區別

環境變量文件是項目中的.env開頭的文件&#xff0c;如下圖&#xff1a; 下圖是VUE2.env文件中的配置&#xff0c;是以VUE_APP開頭的 VUE_APP_PAGE_TITLE系統 VUE_APP_SERVICE_PREFIX/gateway/xxxxx在使用時 只需要 調用 process.env.VUE_APP_SERVICE_PREFIX 就可以獲取到值 而…

php flush實時輸出線上環境好使,本地環境等待一段時間后一次性輸出結果的原因

近期對接deepseek接口時為了擁有較好的用戶體驗&#xff0c;等待答案返回時采用了flush分布輸出&#xff0c;但是線上環境下可以正常分布輸出&#xff0c;同樣代碼在本地總是等待許久后一次性出結果&#xff0c;排查許久&#xff0c;發現竟然是本地和線上不同的php加載模式導致…