最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ explicit顯式關(guān)鍵字的實現(xiàn)

 更新時間:2026年02月02日 10:35:12   作者:帶土1  
explicit關(guān)鍵字用于禁止類的單參數(shù)構(gòu)造函數(shù)進(jìn)行隱式類型轉(zhuǎn)換,本文主要介紹了C++ explicit顯式關(guān)鍵字的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下

一、explicit 關(guān)鍵字的核心定義

explicit 是C++中的修飾符關(guān)鍵字唯一的作用場景是修飾類的構(gòu)造函數(shù),它的核心功能是:禁止編譯器對被修飾的構(gòu)造函數(shù)執(zhí)行「隱式類型轉(zhuǎn)換 / 隱式構(gòu)造」行為。

二、前置知識:什么是「隱式類型轉(zhuǎn)換/隱式構(gòu)造」?

要理解explicit,必須先理解它要禁止的行為是什么。

觸發(fā)隱式構(gòu)造的前提

一個類的構(gòu)造函數(shù)滿足以下條件時,編譯器就具備了「隱式轉(zhuǎn)換」的能力:
? 構(gòu)造函數(shù)是單參數(shù)構(gòu)造函數(shù)(只有1個入?yún)ⅲ?br />? 或,多參數(shù)構(gòu)造函數(shù),但除第一個參數(shù)外,其余參數(shù)都有默認(rèn)值(本質(zhì)等價于「可單參數(shù)調(diào)用」的構(gòu)造函數(shù))。

隱式構(gòu)造的本質(zhì)

編譯器會自動將「單個入?yún)⒌闹怠罐D(zhuǎn)換為「當(dāng)前類的臨時對象」,這個轉(zhuǎn)換過程是編譯器偷偷完成的,不需要程序員手動寫構(gòu)造代碼,所以叫「隱式」。

三、無 explicit 時:隱式構(gòu)造生效(反面示例)

下面的代碼是不加explicit的情況,可以直觀看到隱式構(gòu)造的效果,這也是explicit要解決的場景:

#include <iostream>
using namespace std;

class Test {
public:
    int num;
    // 單參數(shù)構(gòu)造函數(shù):無explicit修飾,支持隱式構(gòu)造
    Test(int n) : num(n) {
        cout << "構(gòu)造函數(shù)執(zhí)行: num = " << num << endl;
    }
};

// 測試函數(shù):入?yún)門est類型對象
void printTest(Test t) {
    cout << "printTest: " << t.num << endl;
}

int main() {
    // 場景1:直接賦值的隱式轉(zhuǎn)換
    Test t1 = 10;  // ? 編譯通過!編譯器自動把 10 → Test(10) 臨時對象 → 賦值給t1
    cout << "t1.num = " << t1.num << endl;

    // 場景2:函數(shù)傳參的隱式轉(zhuǎn)換
    printTest(20); // ? 編譯通過!編譯器自動把 20 → Test(20) 臨時對象 → 傳給函數(shù)
    return 0;
}

運行結(jié)果

構(gòu)造函數(shù)執(zhí)行: num = 10
t1.num = 10
構(gòu)造函數(shù)執(zhí)行: num = 20
printTest: 20

? 結(jié)論:無explicit時,編譯器幫我們完成了 整型值 → Test對象 的隱式轉(zhuǎn)換,代碼能編譯運行,但這種「自動轉(zhuǎn)換」往往是風(fēng)險來源。

四、加 explicit 時:隱式構(gòu)造被禁止(正面示例)

給上述代碼的構(gòu)造函數(shù)加上explicit修飾,代碼如下,所有隱式轉(zhuǎn)換的寫法都會直接編譯報錯

#include <iostream>
using namespace std;

class Test {
public:
    int num;
    // 單參數(shù)構(gòu)造函數(shù):加explicit修飾,禁止隱式構(gòu)造
    explicit Test(int n) : num(n) {
        cout << "構(gòu)造函數(shù)執(zhí)行: num = " << num << endl;
    }
};

void printTest(Test t) {
    cout << "printTest: " << t.num << endl;
}

int main() {
    // 場景1:直接賦值的隱式轉(zhuǎn)換
    Test t1 = 10;  // ? 編譯報錯!explicit禁止了這種隱式轉(zhuǎn)換寫法
    // 場景2:函數(shù)傳參的隱式轉(zhuǎn)換
    printTest(20); // ? 編譯報錯!explicit禁止了這種隱式轉(zhuǎn)換寫法

    return 0;
}

報錯原因

編譯器提示類似:cannot convert 'int' to 'Test' in initialization,核心就是:explicit讓編譯器失去了「自動轉(zhuǎn)換類型」的權(quán)限。

五、加 explicit 后,正確的寫法:顯式構(gòu)造

?? 重要結(jié)論:explicit 只禁止隱式構(gòu)造,完全不影響「顯式構(gòu)造」
explicit修飾的構(gòu)造函數(shù),依然可以正常使用,只是必須手動顯式調(diào)用構(gòu)造函數(shù),這也是C++推薦的「安全寫法」,修改上述main函數(shù)的正確代碼:

int main() {
    // 正確寫法1:標(biāo)準(zhǔn)顯式構(gòu)造(最常用)
    Test t1(10); 
    cout << "t1.num = " << t1.num << endl;

    // 正確寫法2:C++11列表初始化(同樣屬于顯式構(gòu)造)
    Test t2{20};
    cout << "t2.num = " << t2.num << endl;

    // 正確寫法3:函數(shù)傳參時顯式構(gòu)造
    printTest(Test(30));
    printTest(Test{40});

    return 0;
}

運行結(jié)果

構(gòu)造函數(shù)執(zhí)行: num = 10
t1.num = 10
構(gòu)造函數(shù)執(zhí)行: num = 20
t2.num = 20
構(gòu)造函數(shù)執(zhí)行: num = 30
printTest: 30
構(gòu)造函數(shù)執(zhí)行: num = 40
printTest: 40

? 結(jié)論:顯式構(gòu)造的寫法完全不受explicit影響,且邏輯清晰,可讀性更高。

六、explicit 的核心注意事項

? 注意1:explicit 只對「可單參數(shù)調(diào)用的構(gòu)造函數(shù)」有效

explicit的修飾對以下構(gòu)造函數(shù)無意義(加了也不會報錯,但屬于多余寫法):

  1. 無參構(gòu)造函數(shù)(Test());
  2. 真正的多參數(shù)構(gòu)造函數(shù)(無默認(rèn)值,比如Test(int a, int b));
    因為這兩種構(gòu)造函數(shù)本身就無法觸發(fā)隱式構(gòu)造,編譯器沒有轉(zhuǎn)換的依據(jù)。

? 注意2:多參數(shù)+默認(rèn)值的構(gòu)造函數(shù),也需要加 explicit

這是最容易被忽略的坑!比如下面的構(gòu)造函數(shù),本質(zhì)是「可單參數(shù)調(diào)用」,不加explicit依然會觸發(fā)隱式構(gòu)造:

class Test {
public:
    int a, b;
    // 多參數(shù),但第二個參數(shù)有默認(rèn)值 → 等價于「可單參數(shù)調(diào)用」
    Test(int x, int y = 0) : a(x), b(y) {}
};

int main() {
    Test t = 100; // ? 編譯通過!隱式構(gòu)造:100 → Test(100, 0)
    return 0;
}

? 建議:這種構(gòu)造函數(shù)必須加explicit,寫法如下:

explicit Test(int x, int y = 0) : a(x), b(y) {}

? 注意3:C++11擴(kuò)展:explicit 也可以修飾「轉(zhuǎn)換運算符」

C++11標(biāo)準(zhǔn)中,explicit的作用范圍被擴(kuò)大了:除了修飾構(gòu)造函數(shù),還可以修飾類的轉(zhuǎn)換運算符(operator 類型名),作用依然是:禁止自定義類型到其他類型的隱式轉(zhuǎn)換。
示例:

class Test {
public:
    int num = 10;
    // 轉(zhuǎn)換運算符:將Test對象轉(zhuǎn)為int類型
    explicit operator int() const {
        return num;
    }
};

int main() {
    Test t;
    int a = t; // ? 編譯報錯!禁止隱式轉(zhuǎn)換 Test → int
    int b = static_cast<int>(t); // ? 正確:顯式轉(zhuǎn)換,不受影響
    return 0;
}

? 注意4:為什么要禁止隱式構(gòu)造?—— 核心價值

explicit不是語法糖,而是C++的安全機(jī)制,它的設(shè)計初衷是:避免「意外的隱式轉(zhuǎn)換」導(dǎo)致的邏輯錯誤和難以排查的bug。

  • 隱式轉(zhuǎn)換是編譯器的「自動行為」,程序員很容易忽略這個轉(zhuǎn)換過程,導(dǎo)致代碼邏輯和預(yù)期不符;
  • 隱式轉(zhuǎn)換會生成臨時對象,可能帶來不必要的性能開銷(雖然現(xiàn)代編譯器會優(yōu)化,但依然不推薦);
  • 顯式構(gòu)造的代碼可讀性更高,誰看都知道這里是「創(chuàng)建了一個對象」,沒有歧義。

七、最佳實踐(行業(yè)通用規(guī)范)

所有滿足「可單參數(shù)調(diào)用」的構(gòu)造函數(shù),都建議加上 explicit 修飾!

除非你有明確的業(yè)務(wù)需求需要用到隱式構(gòu)造(這種場景極少,比如std::string的構(gòu)造函數(shù)允許const char*隱式轉(zhuǎn)為string,是為了兼容C語言的字符串寫法),否則一律加上explicit,這是C++開發(fā)的「行業(yè)最佳實踐」,也是大廠面試的高頻考點。

? 核心知識點總結(jié)(精華濃縮)

  1. explicit 是修飾符,僅用于修飾類的構(gòu)造函數(shù)(C++11可修飾轉(zhuǎn)換運算符);
  2. 核心作用:禁止編譯器的隱式類型轉(zhuǎn)換/隱式構(gòu)造;
  3. 生效前提:構(gòu)造函數(shù)是「單參數(shù)」或「多參數(shù)+其余參數(shù)有默認(rèn)值」;
  4. explicit后,只能用顯式構(gòu)造Test t(n) / Test t{n}),隱式寫法(Test t = n)編譯報錯;
  5. explicit不影響顯式構(gòu)造,是C++的安全機(jī)制,推薦無腦加;
  6. 本質(zhì)區(qū)別:隱式是「編譯器自動轉(zhuǎn)」,顯式是「程序員手動寫」,顯式代碼更安全、可讀性更高。

到此這篇關(guān)于C++ explicit顯式關(guān)鍵字的實現(xiàn)的文章就介紹到這了,更多相關(guān)C++ explicit顯式關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ 自增、自減運算符的重載和性能分析小結(jié)

    C++ 自增、自減運算符的重載和性能分析小結(jié)

    這篇文章主要介紹了C++ 自增、自減運算符的重載和性能分析小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C語言進(jìn)階之文件操作詳解

    C語言進(jìn)階之文件操作詳解

    這篇文章主要為大家詳細(xì)介紹了C語言進(jìn)階之文件操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C語言全方位講解數(shù)組的使用

    C語言全方位講解數(shù)組的使用

    數(shù)組是一組有序的數(shù)據(jù)的集合,數(shù)組中元素類型相同,由數(shù)組名和下標(biāo)唯一地確定,數(shù)組中數(shù)據(jù)不僅數(shù)據(jù)類型相同,而且在計算機(jī)內(nèi)存里連續(xù)存放,地址編號最低的存儲單元存放數(shù)組的起始元素,地址編號最高的存儲單元存放數(shù)組的最后一個元素
    2022-04-04
  • C/C++中文件的隨機(jī)讀寫詳解及其作用介紹

    C/C++中文件的隨機(jī)讀寫詳解及其作用介紹

    這篇文章主要介紹了C/C++中文件的隨機(jī)讀寫詳解及其作用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • C++入門之vector的底層實現(xiàn)詳解

    C++入門之vector的底層實現(xiàn)詳解

    這篇文章主要為大家介紹了C++入門之vector的底層實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • 詳解C語言中的wait()函數(shù)和waitpid()函數(shù)

    詳解C語言中的wait()函數(shù)和waitpid()函數(shù)

    這篇文章主要介紹了C語言中的wait()函數(shù)和waitpid()函數(shù),注意其在中斷進(jìn)程方面用法的不同,需要的朋友可以參考下
    2015-08-08
  • 內(nèi)部排序之堆排序的實現(xiàn)詳解

    內(nèi)部排序之堆排序的實現(xiàn)詳解

    本篇文章是對堆排序的實現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解C++編程中的sizeof運算符與typeid運算符

    詳解C++編程中的sizeof運算符與typeid運算符

    這篇文章主要介紹了C++編程中的sizeof運算符與typeid運算符,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • C++多重繼承引發(fā)的重復(fù)調(diào)用問題與解決方法

    C++多重繼承引發(fā)的重復(fù)調(diào)用問題與解決方法

    這篇文章主要介紹了C++多重繼承引發(fā)的重復(fù)調(diào)用問題與解決方法,結(jié)合具體實例形式分析了C++多重調(diào)用中的重復(fù)調(diào)用問題及相應(yīng)的解決方法,需要的朋友可以參考下
    2018-05-05
  • C++ primer超詳細(xì)講解順序容器

    C++ primer超詳細(xì)講解順序容器

    本文主要介紹了C++順序容器(vector、deque、list)的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評論

通许县| 体育| 常宁市| 南靖县| 军事| 卓资县| 同心县| 安岳县| 德格县| 天台县| 宜阳县| 绍兴县| 西乌珠穆沁旗| 翁源县| 洛阳市| 元阳县| 张家港市| 屏东县| 浏阳市| 汽车| 海原县| 胶州市| 武穴市| 和政县| 闸北区| 鄄城县| 宣汉县| 黄龙县| 耿马| 互助| 平原县| 彭泽县| 观塘区| 九龙县| 锦州市| 光山县| 绍兴县| 永丰县| 甘孜县| 海门市| 同心县|