C++使用explicit关键词的理解

2023-03-17 14:14:40 浏览数 (1)

❝C 的explicit关键词一般用来构造函数中,让其不能隐式转换。❞

比如有类String

代码语言:javascript复制
struct String 
{ 
    String(int size) 
    {
    } 
};

使用类String我们很自然地会写成这样。

代码语言:javascript复制
String str = 1;
// 隐式转换,相当于String str = String(1);

但如果使用了explicit修饰构造函数则会导致报错。

代码语言:javascript复制
struct String 
{ 
    explicit String(int size) 
    {
    } 
};

// String str = 1; // 编译错误

上面介绍了explicit的使用,大概意思就是限制用户的某一行为。实际上加不加explicit都差不多呀,不加更方便呢。

  默认的隐式转换可以说是编译器的一个特性,虽然会让工程师方便地写代码,但同时也会有副作用。比如:

代码语言:javascript复制
struct String 
{ 
    String(int size) 
    {
    } 
};

void print(const String &str)
{
}

print(3); // 预想打印数字3,却是输出长度为3的空字符串。

虽然不使用explicit关键词可以方便地写少代码,但在某种情况下会导致意想不到的问题。而使用explicit关键词则可以增强代码健壮性,但需要额外多写代码。

什么时候使用explicit呢?

Qt君认为,一般用在构造函数存在单个参数时就需要explicit修饰。

引申

构造函数的多个参数在某些情况下依然需要explicit,但一般情况下不需要添加,因为多个参数的构造函数,在写法上已经会让人去了解到可能存在的问题。比如:

代码语言:javascript复制
struct String 
{ 
    String(int size, int maxSize) 
    {
    } 
};

void print(const String &str)
{
}

print({1, 5});

 上面的列表初始化就已经会让人看到这是一个字符串的初始化,和先前的print(3)明显区分了。

  此外我们还可以使用explicit修饰重载类型符,比如:

代码语言:javascript复制
struct A
{ 
    explicit A(int n) 
    {
    } 

    explicit operator bool() const 
    { 
        return true; 
    }
}; 

A a(1);
bool b = a; // 编译错误,不能隐式转换。

关于更多

更为详细的explicit关键词介绍。https://en.cppreference.com/w/cpp/keyword/explicit

0 人点赞