隐式转换

例子

假设现在你构造了一个Dog类,只需要传入一个age就能创建一只狗

class Dog {
public:
    Dog(int age) { ... } // 只需要一个 int 参数的构造函数
};

// 假设有一个函数,专门用来让狗玩耍
void play(Dog d) {
    // ...
}

正常来说应该这么写

Dog my_dog(3); // 先创建一只3岁的狗
play(my_dog);  // 传进去

但是实际上偷懒了,写为了这样

play(3); 

这时候,C++不会报错,他会自动调用Dog(3)造一只狗。

问题

但是这时候有两个问题
1.如果别人看你的代码,看到了play(3); 回想:不应该是play一只狗嘛?play一个3是啥意思?
2.有时候创建一个对象非常消耗性能或涉及复杂的系统资源,如果仅仅因为传错了一个参数,C++ 就偷偷帮你创建了一个大对象,很容易导致程序崩溃或逻辑混乱。

禁止隐式转换->显式转换

例如下面代码中

explicit TurtleCircle(const std::string &node_name): Node(node_name)

其中explicit是阻止隐式转换
如果有一个启动节点的函数

void startNode(TurtleCircle circle) {
    // 省略代码
}

如果不加上explicit,有人写了

startNode("my_turtle"); 

此时就会创建一个新的TurtleCircle,非常消耗资源。但是如果加了explicit,就会直接报错,就必须写为

startNode(TurtleCircle("my_turtle"));