explicit 用法
explicit用来防止构造函数自动转换
若我们在定义了的构造函数前加上explict,则在我们定义对象时,要想用到该构造函数必须是显示调用,所用隐式的操作都将被认为是错误的。(引用他人代码)
- 1 class Test1
- 2 {
- 3 public:
- 4 Test1(int n) { num = n; } //普通构造函数
- 5 private:
- 6 int num;
- 7 };
- 8
- 9 class Test2
- 10 {
- 11 public:
- 12 explicit Test2(int n) { num = n; } //explicit(显式)构造函数
- 13 private:
- 14 int num;
- 15 };
- 16
- 17 int main()
- 18 {
- 19 Test1 t1 = 12; //隐式调用其构造函数, 成功
- 20 Test2 t2 = 12; //编译错误,不能隐式调用其构造函数
- 21 Test2 t3(12); //显示调用成功
- 22 return 0;
- 23 }
我们再来看另一个例子:
- class one
- {
- public:
- one(){}
- };
- class two
- {
- public:
- two(const one&){}
- };
- void f(two);
- int main()
- {
- one tone;
- f(tone);
- return 0;
- }
有代码中我们就可以看出我们并未定义f(one)这样一个函数,但是我们的程序是运行成功的,这是为什么呢?---隐式转换。当我们调用函数f(tone);时,编译器会会去查找名字为f的这样的函数,若找到他会检查对应的形参类型是否匹配。若不匹配,他还会检查是否可以发生隐式的转换,即这两个不同的类型间可以相互转换吗?若可以仍可以进行调用。否则则会产生编译错误,在我们本程序中,编译器会检查到类two的构造函数。他可以帮助进行隐式转换,故程序可以运行。若我们不想此情况的发生,在two的构造函数前加上explicit即可。即只允许显示的调用该构造函数。
但是这样的隐式转换只能发生一级:如:
- #include <iostream>
- using namespace std;
- class one
- {
- public:
- one(){}
- };
- class two
- {
- public:
- two(const one&){}
- };
- class three
- {
- public:
- three(const two&){}
- };
- void f(three);
- int main()
- {
- one tone;
- f(tone);//error cannot convert one to three
- return 0;
- }