c++ explicit关键字常见的应用场景是类的构造,用于修饰类的构造函数。假如有如下的一个类:
class Cube {
private:
double side;
public:
Cube(double aSide) :side{ aSide } {//constructor
std::cout << "Cube constructor called" << "n";
};
double volume() {//Caculate volume of a cube
return side * side * side;
};
bool hasLargerVolumeThan(Cube aCube) {//Compare volume of a cube with another
return volume() > aCube.volume();
};
};
运行如下的代码:
int main(){
Cube box1{ 7.0 };
Cube box2{ 3.0 };
if (box1.hasLargerVolumeThan(box2)) {
std::cout << "box1 is larger than box2." << "n";
}
else {
std::cout << "Volume of box1 is less than or equal to that of box2."
<< "n";
}
std::cout << "volume of box1 is "
<< box1.volume()
<< "n";
if (box1.hasLargerVolumeThan(50.0)) {
std::cout << "Volume of box1 is greater than 50"
<< "n";
}
else {
std::cout << "Volume of box1 is less than or equal to 50"
<< "n";
}
std::cout << "Volume of box1 is less than or equal to 50"
<< "n";
return 0;
}
运行结果为:
将class以UML表示出来:
当调用Cube类的hasLargerVolumeThan()函数时,参数aCube的类型是Cube,照理来说是只能对比两个Cube类型的 “Volume()” 的大小。但是从第二次对比行为来看,传入的参数是浮点型的 50.0 而不是一个Cube型的变量,类型对不上理应是报错,但实际上没有报错,通过了编译。这是因为将浮点型的传入参数隐式转换成了Cube类型,在转换的过程中,需要构造一个Cube类型,所以会调用Cube类的构造函数,而传入的浮点型参数成为了构造函数的传入参数,用于构造一个新的Cube类型。新构造的Cube型参数的 “side” 为 50.0,则其 “Volume” 便为 50.0 x 50.0 x 50.0=125000.0 ,所以box1的 “Volume” 343 是小于等于125000.0的。
而explicit关键字的作用就是不再允许这种转换行为,只允许参数类型能够符合的情况。比如:
explicit Cube(double aSide) :side{ aSide } {//constructor
std::cout << "Cube constructor called" << "n";
};
修改后可以发现原来的不报错的函数报错,不再能通过编译:
参考资料
[1] Beginning C++17,5th Edition . Lvor Horton . Peter Van Weert . chapter 11.4.7



