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();

这时, 我们或可以强制进行类型转换, 也可显示调用转换函数

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