C++類的 explicit 關鍵字和隱式轉換

C++類的 explicit 關鍵字和隱式轉換

explicit 關鍵字用於 C++的類定義中,其作用是禁止隱式轉換和複製初始化操作:

The explicit specifier specifies that a constructor or conversion
function (since C++11) doesn’t allow implicit conversions or
copy-initialization. It may only appear within the decl-specifier-seq
of the declaration of such a function within its class definition.

這裏介紹一個概念:轉換構造函數, 它的英文定義如下:

A constructor with a single non-default parameter (until C++11) that
is declared without the function specifier explicit is called a
converting constructor.

大意就是說不用 explicit 關鍵字聲明, 只包含一個非默認參數的構造函數.
具體使用用一個例子來說明:

#include <iostream>

using std::cout;

struct A
{
    A(int) { cout << "A(int)\n"; }      // converting constructor
    A(int, int) { cout << "A(int, int)\n"; } // converting constructor (C++11)
    A(const A&) {cout << "A(const A&)\n";}
    operator bool() const { return true; }
};

struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator bool() const { return true; }
};

int main()
{
    A a1 = 1; // copy-initialization, call A(int)
    A a2(2); // direction-initialization, call A(int)
    A a3 {4, 5}; //direction-list-initialization, call A(int int)
    A a4 = {4, 5};//copy-list-initialization, call A(int int)
    A a5 = (A)1; //explicit cast

    if(a1) //copy-initializat, call operator bool
        cout << "true\n";

    bool na1 = a1;
    cout << std::boolalpha << na1 << '\n';
    bool na2 = static_cast<bool>(a1); 
    cout << std::boolalpha << na2 << '\n';

    //B b1 = 1; //no viable conversion from 'int' to 'B'
    B b2 = (B)1; 
    B b3(2);
    B b4 {4, 5};
    //B b5 = {4, 5};//chosen constructor is explicit in copy-initialization

    if(b2)
        cout << "true\n";

    //bool nb1 = b2;//no viable conversion from 'B' to 'bool'
    bool nb1 = b2.operator bool();
    bool nb2 = static_cast<bool>(b2); 
}

上例中選用了兩個 struct, 這裏出於使用方便, 你完全可以可用 class, 不過需要使用 public 聲明成員函數. A 中沒有使用 explicit 關鍵字, 所以對於 A 隱式轉換和複製初始化都可以順利進行, 但是與之相對 B 由於使用了 explicit 聲明, 隱式轉換和複製初始化被禁止.

B b1 = 1; 
//no viable conversion from 'int' to 'B'
 B b2 = (B)1; //explicit conversion
B b5 = {4, 5};
//chosen constructor is explicit in copy-initialization
 bool nb1 = b2;
 //no viable conversion from 'B' to 'bool'
 bool nb1 = b2.operator bool();

這時, 我們或可以強制進行類型轉換, 也可顯示調用轉換函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章