在C++编程中,类型转换是一个常见的操作,但不当的转换可能导致编译器警告、运行时错误或代码可读性降低。本文将探讨如何安全、高效地进行类型转换,特别是将Win32 API中的BOOL类型转换为C++的bool类型。
在Windows编程中,经常需要检查窗口句柄的有效性。一个常见的错误是直接将BOOL类型的返回值赋值给bool类型的变量,这会导致编译器警告:
void motivation(HWND hWnd) {
bool b = ::IsWindow(hWnd);
}
上述代码会产生警告:
warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
警告提示,直接将BOOL类型转换为bool类型可能会影响性能。
一个常见的错误做法是使用比较操作符来消除警告:
void wrong(HWND hWnd) {
bool b = (::IsWindow(hWnd) == TRUE);
}
然而,这种做法是未定义行为,因为Win32文档指出,如果窗口句柄标识了一个存在的窗口,返回值是非零值;如果窗口句柄没有标识存在的窗口,返回值是零。
正确的做法是使用比较操作符来检查返回值是否非零:
void right(HWND hWnd) {
bool b = (::IsWindow(hWnd) != 0);
}
这样既消除了警告,也保证了代码的正确性。
为了进一步简化代码,提高可读性和安全性,可以使用poost命名空间中的boolean_cast工具:
void good(HWND hWnd) {
bool b = boolean_cast(::IsWindow(hWnd));
}
boolean_cast工具可以安全地在bool、BOOL和VARIANT_BOOL类型之间进行转换。
auto_boolean工具进一步简化了类型转换,它使用目标对象的类型作为目标类型:
void best(HWND hWnd) {
bool b = auto_boolean(::IsWindow(hWnd));
}
这样,不需要显式指定目标类型,编译器会自动调用boolean_cast进行转换。
boolean_cast的实现如下:
template
TargetT boolean_cast(SourceT b) {
typedef boolean_converter converter_t;
return converter_t::convert(b);
}
boolean_cast将任务委托给boolean_converter类模板,实际工作由模板完成。
auto_boolean的实现如下:
template
struct auto_boolean_type {
explicit auto_boolean_type(SourceT b) : m_b(b) { }
template
operator TargetT() const {
return boolean_cast(m_b);
}
private:
SourceT m_b;
};
template
auto_boolean_type auto_boolean(SourceT b) {
return auto_boolean_type(b);
}