概念引入
构造函数不仅可以构造并初始化对象,对于具有单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换作用。
而explicit关键字,恰恰可以禁止编译器的隐式类型转换。
1.explicit 介绍
explicit 的作用是声明类构造函数是显式调用,而非隐式调用。
为什么是修饰单参构造函数呢?
因为无参构造函数和多参构造函数本身就是显示调用的,加上explicit也没意义。
1.1 显示调用和隐式调用
class Date { public: // 1.无参构造函数 Date() { cout << "无参调用构造函数" << endl; } //2. 单参构造函数 Date(int year) :_year(year) { cout << "单参数调用构造函数" << endl; } //Date(int year, int month = 1, int day = 1) // :_year(year) // ,_month(month) // ,_day(day) //{ // cout << "多参构造函数调用" << endl; //} private: int _year; int _month; int _day; }; int main() { Date d1; Date d1(1); // 直接调用构造函数 Date d2 = 1; //隐是调用:隐式类型转换:构造+拷贝构造+优化 -> 直接调用构造 return 0; }
显式调用:直接显示的调用,如Date d1调用无参构造函数;或者Date d1(1),调用单参构造函数。
隐式调用:不直接调用,编译器会自己调用,如Date d2 = 1,隐式调用单参构造函数。
1.2 explicit意义
上面的式调用看上去是把 int 类型的数据直接赋给了 Date 类型,这种代码存在隐式类型转换,虽然表面没有错误,但是后面如果程序出错,很难排查错误。
因此,为了防止这种隐式转换可能带来的风险,需要把单参构造函数声明为显示调用的,即禁止隐式调用,加上explicite即可。如下:
可以从这里可以看出,explicit禁止了隐式转换,让程序更有健壮性。