C++ explicit 构造函数

本文主要参考《C++ Primer 4e》第12.4.4小节,以及《Effective C++ 3e》第0章。


可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换。这句话有点绕,我们来看一个例子。

class Sales_item {
public:
	Sales_item() : units_sold(0), revenue(0.0) {}
	// default argument for book is the empty strings
	Sales_item(const std::string &book = "") :
		isbn(book), units_sold(0), revenue(0.0) {}
	Sales_item(std::istream &is);
	bool same_isbn(const Sales_item &rhs) const
	{ return isbn == rhs.isbn; }
private:
	std::string isbn;
	unsigned units_sold;
	double revenue;
};

这里定义了三个构造函数,后面的两个构造函数都定义了一个隐式转化。因此,在期待一个Sales_item类型对象的地方,可以使用一个string或一个istream:

Sales_item item;
string null_book = "9-999-99999-9";
// ok: builds a Sales_item with 0 units_sold and revenue from
// and isbn equal to null_book
item.same_isbn(null_book);

same_isbn期待一个Sales_item对象,于是编译器在此处接受一个string对象null_book,并调用Sales_item(const std::string &book)生成一个新的Sales_item对象,该新对象被传递给same_isbn。

更成问题的是从istream到Sales_item的隐式转化:

// ok: uses the Sales_item istream constructor to build an object
// to pass to same_isbn
item.same_isbn(cin);

这段代码将cin隐式转化为Sales_item对象。

这些行为在多数情况下都不是我们想要的,如何抑制这种情况?

可以通过将构造函数声明为explicit,来防止在需要隐式转化的上下文使用构造函数:

class Sales_item {
public:
	Sales_item() : units_sold(0), revenue(0.0) {}
	// default argument for book is the empty strings
	explicit Sales_item(const std::string &book = "") :
		isbn(book), units_sold(0), revenue(0.0) {}
	explicit Sales_item(std::istream &is);
	bool same_isbn(const Sales_item &rhs) const
	{ return isbn == rhs.isbn; }
private:
	std::string isbn;
	unsigned units_sold;
	double revenue;
};

explicit关键字只能用于类内部的构造函数声明上,在类的定义体外部所做的定义上不再重复它:

// error: explicit allowed only on constructor declaration in class header
explicit Sales_item::Sales_item(istream &is)
{
	is >> *this;	// use Sales_item input operator to read the members
}

通常,除非有明显的理由想要定义隐式转化,否则,单形参构造函数应该为explicit。将构造函数设置为explicit可以避免错误,并且当转换用用时,用户可以显式地构造对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值