explicit防止隐式转换

c++允许隐式转换,没有加入explicit限定符的都看作是能够实现隐式转换的,但有些时候不期望这样做。

例如:
[php]
class CBook
{
public:
CBook(std::string name) : m_name(name), m_width(0), m_height(10) {}
int Compare(CBook& book);
std::string m_name;
int m_width;
int m_height;
};

CBook book1("book1");
book1.m_width = 10;
book1.m_height = 20;
int result = book1.Compare("book2");
[/php]
在这里调用Compare函数时,本来是需要CBook参数的,但由于CBook的构造函数参数是std::string,这里编译器自动使用”book2″临时构造一个CBook对象,同时将这个临时对象传给Compare函数,并在离开Compare函数时自动析构,这就是隐式转换的过程。

但若需要比较book2的width和height值,那么就无法修改,这样做就是错误的,需要使用explicit来防止隐式转换。如下:
[php]
class CBook
{
public:
explicit CBook(std::string name) : m_name(name), m_width(0), m_height(10) {}
int Compare(CBook& book);
std::string m_name;
int m_width;
int m_height;
};

CBook book1("book1");
book1.m_width = 10;
book1.m_height = 20;
CBook book2("book2");
book2.m_width = 15;
book2.m_height = 22;
int result = book1.Compare(book2);
[/php]
google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。

effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期(往往也不被期望)的类型 转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit。我鼓励你遵循相同的政策。

Comments are closed.