背景:我们在程序中往往需要对一个类实例的合法性进行检查,大部分的程序员都会想到在类的方法中提供一个方法检查合法性(比如提供一个IsValid函数),但是还有一个更好的方法就是提供一个类型转换的operator,下面就来介绍下。
- 方法1:传统方法:
class MyClass {
public:
bool IsValid() {return true;}
};
int main()
{
MyClass obj;
if (obj.IsValid()) {
// do something
}
return 0;
}
- 方法2:提供转换操作符:
class MyClass {
public:
operator bool() {return true;} // 转换操作符,写法是operator TypeName()
};
int main()
{
MyClass obj;
if (obj) {
// do something
}
return 0;
}
可以看的出来,如果提供了转换操作符之后,在应用代码中直接就可以写成if (xxx)了,比较的方便。
转换操作符的写法:operator TypeName()。
但是此方法会带来一些额外的问题,看下面的代码:
#include <iostream>
class MyClass {
public:
operator bool() {return true;} // 转换操作符,写法是operator TypeName()
};
int main()
{
MyClass obj1, obj2;
if (obj1 == obj2) { // 这里不应该编译通过
// do something
}
return 0;
}
当我们比较两个类实例时,由于我们提供了bool类型的转换操作符,所以编译器会自动将obj1和obj2先转换为bool变量,然后进行比较,这显然不是我们想要的。
幸好,在C++11之后提供了“explicit”关键字,可以很优雅的解决这个问题。
- 建议方法:使用转换操作符,并且在操作符之前使用C++11 explicit关键字
class MyClass {
public:
explicit operator bool() {return true;} // 转换操作符,并且前面加explicit关键字
};
int main()
{
MyClass obj1, obj2;
// 编译通过
if (obj1) {
// do something
}
// 编译不通过
if (obj1 == obj2) {
// do something
}
return 0;
}
可以看到,加了“explicit”关键字之后,编译器就不会自动将MyClass类型对象实例自动转换为bool变量了,原来的两个类实例比较代码能编译通过的问题解决了。
网友评论