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

C++構(gòu)造函數(shù)中explicit詳解

 更新時間:2025年12月03日 11:07:26   作者:湫兮之風  
explicit關(guān)鍵字用于修飾單參數(shù)構(gòu)造函數(shù)或可以看作單參數(shù)的構(gòu)造函數(shù),阻止編譯器進行隱式類型轉(zhuǎn)換或拷貝初始化,本文就來介紹explicit的使用,感興趣的可以了解一下

在 C++ 編程中,構(gòu)造函數(shù)是類的核心部分之一。我們常常使用構(gòu)造函數(shù)來初始化對象。但是,如果不加限制,某些構(gòu)造函數(shù)可能會被 隱式調(diào)用,從而帶來一些意料之外的行為。

為了解決這個問題,C++ 提供了 explicit 關(guān)鍵字。

1. 什么是explicit

在 C++ 中,explicit 關(guān)鍵字用于修飾 單參數(shù)構(gòu)造函數(shù)可以看作單參數(shù)的構(gòu)造函數(shù),阻止編譯器進行 隱式類型轉(zhuǎn)換拷貝初始化。

  • 默認情況下,單參數(shù)構(gòu)造函數(shù)既可以顯式調(diào)用,也可以被編譯器用來進行隱式類型轉(zhuǎn)換。
  • explicit 告訴編譯器:這個構(gòu)造函數(shù)只能顯式調(diào)用,不能用于隱式轉(zhuǎn)換。

2. 隱式轉(zhuǎn)換的問題

來看一個例子:

#include <iostream>
using namespace std;

class Fraction {
private:
    int numerator;
    int denominator;

public:
    Fraction(int num, int den = 1) : numerator(num), denominator(den) {}
    void print() const {
        cout << numerator << "/" << denominator << endl;
    }
};

int main() {
    Fraction f1 = 5;  // 隱式調(diào)用 Fraction(5, 1)
    f1.print();       // 輸出:5/1
}

在上面的例子中:

  • Fraction f1 = 5; 本質(zhì)上是調(diào)用 Fraction(5, 1),因為編譯器允許用 int 隱式轉(zhuǎn)換成 Fraction
  • 雖然看似方便,但有時會帶來 不可控的隱式轉(zhuǎn)換,導(dǎo)致邏輯錯誤或二義性。

3.explicit的使用示例

基本用法

如果我們在構(gòu)造函數(shù)前加上 explicit

class Fraction {
private:
    int numerator;
    int denominator;

public:
    explicit Fraction(int num, int den = 1) : numerator(num), denominator(den) {}
    void print() const {
        cout << numerator << "/" << denominator << endl;
    }
};

int main() {
    Fraction f1(5);     // ? 顯式調(diào)用,可以
    // Fraction f2 = 5; // ? 編譯錯誤,不能隱式轉(zhuǎn)換
}
  • Fraction f1(5); 依然可以顯式調(diào)用。
  • Fraction f2 = 5; 會報錯,因為 explicit 禁止了隱式轉(zhuǎn)換。

多參數(shù)構(gòu)造函數(shù)

有時構(gòu)造函數(shù)有多個參數(shù),但如果除第一個外的參數(shù)都有默認值,它依然算作 單參數(shù)構(gòu)造函數(shù),也可能引發(fā)隱式轉(zhuǎn)換。

class Fraction {
public:
    explicit Fraction(int num, int den = 1) { /* ... */ }
};

這里如果沒有 explicit,表達式 Fraction f = 5; 依然會成立。

4. C++11 之后的擴展

(1)explicit用于轉(zhuǎn)換運算符

在 C++11 之前,類的類型轉(zhuǎn)換函數(shù)(比如 operator bool)會允許隱式轉(zhuǎn)換:

class Test {
public:
    operator bool() const { return true; }
};

int main() {
    Test t;
    if (t) {  // 隱式調(diào)用 operator bool()
        cout << "True" << endl;
    }
}

但有時我們并不希望這種隱式轉(zhuǎn)換。C++11 允許寫成:

class Test {
public:
    explicit operator bool() const { return true; }
};

int main() {
    Test t;
    // if (t) { } // ? 錯誤,不能隱式轉(zhuǎn)換
    if (static_cast<bool>(t)) {  // ? 必須顯式轉(zhuǎn)換
        cout << "True" << endl;
    }
}

(2) C++20 的explicit(bool)

C++20 引入了更靈活的語法:explicit(bool)。
這讓我們可以根據(jù)編譯期常量決定是否允許隱式調(diào)用。

struct A {
    explicit(true) A(int) {}   // 永遠顯式
    explicit(false) A(double) {} // 永遠允許隱式
};

這種寫法在模板編程中很有用。

5. 最佳實踐

  1. 幾乎總是給單參數(shù)構(gòu)造函數(shù)加 explicit
    這樣可以避免隱式轉(zhuǎn)換帶來的混亂,除非你確實需要這種轉(zhuǎn)換。

  2. 轉(zhuǎn)換運算符應(yīng)當盡量顯式
    尤其是 operator bool,因為隱式轉(zhuǎn)換到 bool 可能導(dǎo)致奇怪的條件判斷。

  3. 允許隱式轉(zhuǎn)換的場景
    如果你的類本質(zhì)上就是包裝某個類型(比如 string_view 可以從 const char* 隱式轉(zhuǎn)換),那么允許隱式轉(zhuǎn)換可以讓使用更加自然。

總結(jié)

  • explicit 的主要作用:防止構(gòu)造函數(shù)或轉(zhuǎn)換運算符被隱式調(diào)用。
  • 在單參數(shù)構(gòu)造函數(shù)和轉(zhuǎn)換運算符中使用最為常見。
  • 自 C++11 起,還能用于 operator bool;C++20 引入 explicit(bool),進一步增強靈活性。
  • 最佳實踐:默認加上 explicit,除非你有充分理由允許隱式轉(zhuǎn)換。
  • 關(guān)鍵字explicit只對一個實參的構(gòu)造函數(shù)有效,需要多個實參的構(gòu)造函數(shù)不能用于執(zhí)行隱式轉(zhuǎn)換,所以無需將這些構(gòu)造函數(shù)指定為explicit的。
  • 只能在類內(nèi)聲明構(gòu)造函數(shù)時使用explicit關(guān)鍵字。

補充

  • 接受一個單參數(shù)的const char*的string構(gòu)造函數(shù)不是explicit的
  • 接受一個容量參數(shù)的vector構(gòu)造函數(shù)是explicit的

到此這篇關(guān)于C++構(gòu)造函數(shù)中explicit詳解的文章就介紹到這了,更多相關(guān)C++構(gòu)造函數(shù)explicit內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

大冶市| 普兰县| 阿荣旗| 海南省| 海宁市| 正安县| 盖州市| 双流县| 肥西县| 沙湾县| 仁寿县| 沙河市| 兰考县| 扎赉特旗| 榆社县| 湛江市| 大同市| 河南省| 锡林浩特市| 盘锦市| 竹山县| 错那县| 辽阳市| 荣成市| 元谋县| 友谊县| 高密市| 团风县| 龙里县| 焦作市| 镇沅| 瑞金市| 印江| 保定市| 景谷| 竹溪县| 汾阳市| 安龙县| 水城县| 林西县| 天长市|