构造器 explicit

explicit关键字用来修饰构造函数,为了防止隐式使用拷贝构造函数的。
对下面的例子:
class T
{
public:
  explicit T(){};  //没有效果。因为default constructor不会参加隐式转换
  explicit T(int i){};      //good
  explicit T(int i, double){};    //没有效果。因为本constructor有多个参数,不会参加隐式转换
  explicit T(T const &t){};    //bad design  
};

T t = 1; //error. 不能从int转换到T
T t2(2);  //ok. 显示调用.
T t3 = T(3);
//当拷贝构造函数为explicit时:error. no copy constructor available Or   copy constructor is declared /'explicit/'
//当拷贝构造函数不为explicit时:ok. 但不会调用copy constructor.
//我猜想,copy constructor用explicit修饰时,表示作者不容许任何形如T obj1 = obj2;行为

T t4 = t2;  //error.原因与T t3 = T(3);同
/*注意:当类T是下面定义时:
  class T
  {
  public:
     T(int i){}     //not explicit
     explicit T(T const &t){} //explicit
     operator int(){ return 1; } //
  };
  T t4 = t2;  //ok.编译器会:先t2 -> int,再T(int)
  //即explicit T(T const &t){}只是将这个函数从可能的转换集合中排除了, 如果还有其它的路径,也是可以的。
*/
T t5(t2);  //ok.显示调用

总结:compile在构造类的一个对象上做的小动作太多了,为了使代码清晰,推荐:
1. 总是定义一个default constructor和一个copy constructor,都不要声明为explicit
2. 如果类的成员有非数值类型(比如指针,类对象,数组),总是定义一个copy constructor,不要声明为explicit如果没有,如果bitewise copy足够好的化,可不定义copy constructor,
3. 定义其它有单个参数的constructor时,声明为explicit
4. 定义对象时总是用显示调用的方式,而不是用赋值符/'=/'。
  这点最重要。
参考:
class T
{
public:  
   T(): value(0) {}  //不采用缺省值的方案,更清晰。(普通的函数可以。)
   T(T const &t): value(t.i) {}
   explicit T(int i): value(i) {}  //使用explicit关键字
private:
   int value;
};  
void test(T t){}  
int main()
{
   T t;
   T t2(t);
   T t3(3);
   //T t4 = 3; //不推荐
   //T t5 = t; //不推荐
   
   test(t);
   test(t2);
   test(t3);
   //test(4); //4不能隐式转换为T
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值