理解c++中explicit关键字的作用
理解c++中explicit关键字的作用
explicit 关键字的作用是防止构造函数被隐式调用,从而避免意外的类型转换
#include <iostream>
class Vec3 {
public://构造函数没有被explicit修饰Vec3(float value): x(value), y(value), z(value){}Vec3(float val1, float val2, float val3): x(val1), y(val2), z(val3){}void print() const {std::cout << "x: " << x << ", y: " << y << ", z: " << z << std::endl;}
private:float x, y, z;
};int main() {Vec3 v1(1.0f); //显式调用单值构造函数v1.print();Vec3 v2 = 1.0f;//由于vec3构造函数没有被explicit修饰,所以可以发生隐式调用,发生隐式转换,float转为vec3v2.print();Vec3 v2(1.0,2.0,3.0);//Vec3 v2 = (1.0, 2.0, 3.0);//这个是错误的v2.print();return 0;
}
如果构造函数没有被explicit修饰,则允许发生隐式调用,而隐式调用会发生隐式转换,即float转换为自定义vec3
Vec3 v2 = 1.0f; //隐式调用构造函数,有点像赋值操作,使得读代码的人有点迷惑,可以在单参数构造函数前添加explicit禁用这种调用构造函数的方式
explicit 只能用于修饰单参数构造函数,不能用于普通成员函数或静态函数
隐式转换可能带来以下不良影响:
意外行为:隐式转换可能导致程序行为与预期不符,尤其是在类型不匹配或转换规则复杂时。
性能问题:隐式转换可能引入额外的开销,例如创建临时对象或调用额外的构造函数。
代码可读性降低:隐式转换可能使代码难以理解,开发者可能无法直观地看出转换发生的位置和原因。
类型安全性降低:隐式转换可能导致类型安全问题,例如将一个类型错误地转换为另一个类型,导致潜在的运行时错误。
调试困难:隐式转换可能隐藏问题的根源,增加调试的复杂性。
为了防止隐式转换带来的不良影响,我们还是对单参数构造函数使用explicit修饰,防止隐式调用单参数构造函数
#include <iostream>class Vec3 {
public:// 使用 explicit 防止隐式转换//构造函数explicit Vec3(float value) : x(value), y(value), z(value) {}void print() const {std::cout << "Vec3(" << x << ", " << y << ", " << z << ")" << std::endl;}private:float x, y, z;
};int main() {Vec3 v1(1.0f); // 正确:显式调用构造函数v1.print();// Vec3 v2 = 1.0f; //隐式调用构造函数,错误:explicit 禁止隐式转换// v2.print();return 0;
}
//禁用隐式调用单参数构造函数
Vec3 v2 = 1.0f //无法将浮点类型float转换为类Vec3
//只允许显式调用单参数构造函数
Vec3 v1(1.0f);
隐式调用单参数构造函数由于explicit修饰而被禁用