Skip to the content.

C++的explicit

Contact me


或许很多人没有用过C++的explicit,但是在一些情况下如果对隐式转换有要求的话,这个关键字还是很必要的。

class MyClass
{
public:
    MyClass(int a);
    ~MyClass();
};

MyClass::MyClass(int a){
    std::cout << "constract" << std::endl;
}

MyClass::~MyClass(){
    std::cout << "deconstract" << std::endl;
}


void fun(MyClass mc) {
    std::cout << "fun" << std::endl;
}

int main(int argc, char const *argv[])
{
    fun(5);
    std::cout << "end" << std::endl;
    return 0;
}

这段代码输出为:

constract
fun
deconstract
end

注意到fun的参数是MyClass,而我们传入了一个整数,竟然没有报错,程序做了一件事就是拿这个整数构建了一个MyClass对象,然后fun调用完成后销毁。这个特性很方面,但是有些时候这个转换并不符合预期,比如我们还有个fun的参数是double,那么调用的就是这个参数为double的函数了,因为这个转换更直接(对于C++而言)。所以我们有时候需要对这种转换做下控制,不能隐式的转换,这个时候explicit就派上用场了,我们只需要在构造函数前面加入explicit

explicit MyClass(int a);

这样,程序在编译的时候就报错了,提示不能进行类型转换,我们的目的也达到了。

这个转换只能做一次,也就是说如果你的程序有另一个类Test可以接收一个MyClass的对象,fun的参数是Test,那么是无法完成的,因为这需要两次转换。也就是说C++会努力寻找离你目标最近的那个转换,且只做一次,且有优先顺序,例如int转为double就比转为MyClass更优先。

如果程序要求可读性更好的话,可以使用explicit避免这种隐式转换。但是你依旧可以使用static_cast做这个转换,即使explicit存在。