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

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

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

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

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

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

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

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

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

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

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

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

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

#include <iostream>
using namespace std;

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

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

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

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

運(yùn)行結(jié)果

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

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

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

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

#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() {
    // 場(chǎng)景1:直接賦值的隱式轉(zhuǎn)換
    Test t1 = 10;  // ? 編譯報(bào)錯(cuò)!explicit禁止了這種隱式轉(zhuǎn)換寫法
    // 場(chǎng)景2:函數(shù)傳參的隱式轉(zhuǎn)換
    printTest(20); // ? 編譯報(bào)錯(cuò)!explicit禁止了這種隱式轉(zhuǎn)換寫法

    return 0;
}

報(bào)錯(cuò)原因

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

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

?? 重要結(jié)論:explicit 只禁止隱式構(gòu)造,完全不影響「顯式構(gòu)造」!
explicit修飾的構(gòu)造函數(shù),依然可以正常使用,只是必須手動(dòng)顯式調(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ù)傳參時(shí)顯式構(gòu)造
    printTest(Test(30));
    printTest(Test{40});

    return 0;
}

運(yùn)行結(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 的核心注意事項(xiàng)

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

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

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

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

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

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

int main() {
    Test t = 100; // ? 編譯通過(guò)!隱式構(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)換運(yùn)算符」

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

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

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

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

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

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

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

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

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

? 核心知識(shí)點(diǎn)總結(jié)(精華濃縮)

  1. explicit 是修飾符,僅用于修飾類的構(gòu)造函數(shù)(C++11可修飾轉(zhuǎn)換運(yù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)編譯報(bào)錯(cuò);
  5. explicit不影響顯式構(gòu)造,是C++的安全機(jī)制,推薦無(wú)腦加;
  6. 本質(zhì)區(qū)別:隱式是「編譯器自動(dòng)轉(zhuǎn)」,顯式是「程序員手動(dòng)寫」,顯式代碼更安全、可讀性更高。

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    詳解C++編程中的sizeof運(yùn)算符與typeid運(yùn)算符

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

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

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

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

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

最新評(píng)論

信宜市| 湟源县| 定日县| 定远县| 财经| 湘潭市| 石柱| 清流县| 延寿县| 大名县| 革吉县| 金昌市| 邛崃市| 浙江省| 桂林市| 平昌县| 偃师市| 南昌县| 永吉县| 华坪县| 泰顺县| 囊谦县| 峨眉山市| 金乡县| 驻马店市| 蒙城县| 共和县| 剑川县| 汪清县| 麻城市| 林西县| 阳春市| 恭城| 勃利县| 阳新县| 江川县| 盖州市| 汝阳县| 大冶市| 博罗县| 永州市|