explicit用法

  使用关键字explicit的一条黄金法则是:
对于所有只需提供一个参数就能调用的构造函数,除非你想要利用它进行隐式转换,否则一律将该构造函数声明为explicit。

  下面来解释以下为什么要这样做:
  编译器在调用函数时如果传入实参与函数形参类型不一致时可以采用隐式转换来转换实参类型使其与形参保持一致。这意味着编译器可以使用构造函数(其形参表中只有一个参数)来进行隐式转换以得到正确的参数类型。
举个例子:

//Foo 类有一个可以用于隐式转换的构造函数
class Foo   
{
public:
  // single parameter constructor, can be used as an implicit conversion
  Foo (int foo) : m_foo (foo) 
  {
  }

  int GetFoo () { return m_foo; }

private:
  int m_foo;
};

//DoBar函数有一个Foo类型的形参
void DoBar (Foo foo)
{
  int i = foo.GetFoo ();
}

//在main函数中调用DoBar函数
int main ()
{
  DoBar (42);
}

  上例中,在main函数中调用DoBar函数时传入的实参不是Foo类的对象,而是一个int型整数。然而,因为Foo类存在一个构造函数,它可以将int型整数作为参数用于构造一个Foo类对象,而这个Foo类对象刚好可以作为DoBar的实参。编译器允许进行上述操作。
  但是,如果在上例中的构造函数前面加上explicit,编译器就会被禁止进行隐式转换,因此再次执行DoBar(42)就会发生编译错误,此时要想正确调用DoBar函数,还能这样:DoBar(Foo(42))。
  有人可能会问:什么时候需要禁止这种隐式类型转换(意外地调用了构造函数)呢?看一个下面这样的例子:
  你有一个MyString类,它有一个这样的构造函数:构造一个给定长度的字符串。同时你有这样的函数:print(const MyString&),还有一个重载它的函数:print(char *string).这时,你想要执行print("3")语句,但是由于粗心,你错误地执行了printf(3)。你想要打印3,但结果却打印了一个空字符串(其长度为3)。

参考文献:

  1. stack overflow explict
  2. cplusplus reference forum
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值