原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/17006543
有时候构造函数的隐式转换可以帮我们不少忙,但有时候它也会帮倒忙。所以我们应该要控制它,而不是让它无脑操作。
先看一段代码。
#include "stdafx.h" using namespace std; class A { public: A(int v):var(v){};//带一个int型值的构造函数 bool isSame(const A& ref) const {return var==ref.var;}//判等函数 private: int var;//成员变量var }; int _tmain(int argc, _TCHAR* argv[]) { A a(5);//构造a对象 A b(5);//构造b对象 if (a.isSame(b)) cout<<"a==b"<<endl; else cout<<"a!=b"<<endl; }
由于构造函数需要传入一个int型初始值,因此可以认为这是一个隐式转换,把一个int型值转换为一个A类型的对象。所以如果修改main函数为如下代码。
int _tmain(int argc, _TCHAR* argv[]) { A a(5);//构造a对象 if (a.isSame(5))//这里会因为构造函数的隐式转换,因而正确执行isSame cout<<"a==b"<<endl; else cout<<"a!=b"<<endl; }这看起来不错,好像还省了不少力气,但是这样的使用依赖于用户是否有相应的需求,有时候它将成为一个bug。所以更好的办法是抑制这种由构造函数引起的隐式转换。
在构造函数中引入explicit可以帮我们解决这个问题。
class A { public: explicit A(int v):var(v){};//引入explicit关键字 bool isSame(const A& ref) const {return var==ref.var;} private: int var; }; int _tmain(int argc, _TCHAR* argv[]) { A a(5); if (a.isSame(5)) cout<<"a==b"<<endl; else cout<<"a!=b"<<endl; }看看结果:
error C2664: “A::isSame”: 不能将参数 1 从“int”转换为“const A &” 1> 原因如下: 无法从“int”转换为“const A” 1> class“A”的构造函数声明为“explicit”好了,这样一来构造函数就无法进行隐式转换,
这时候仍想进行转换的话,显式使用构造函数吧。
int _tmain(int argc, _TCHAR* argv[]) { A a(5); if (a.isSame(A(5)))//显式使用构造函数 cout<<"a==b"<<endl; else cout<<"a!=b"<<endl; }
除非有明显的理由想利用构造函数定义的隐式转换,否则设置explicit可以避免一些错误,当需要进行转换的时候,由用户显式地调用构造函数。当然C++的临时对象都是const,如果isSame函参不是const型,则隐式调用构造函数时生成的临时对象也无法传入。