【问题】
除了wchar_t(它是C中的一个typedef)之外,bool是自从ARM以外唯一一个C++新添的内置类型。如果不添加这个bool,能否用已有的数据达到相同的效果呢?如果能,请给出一个实现,如果不能,请说出可能的实现方法都有哪些缺陷?
【解答】
不能,bool明确添加作为C++的基本类型(并保留true和false关键字)没因为它们(bool型和true,false)没法通过现有的语言特性准确实现。
下列四种方法实现都有缺陷:
第一种方法:typedef(评价:8.5/10)
这种方法一般为typedef <something> bool;典型如下:
typedef int bool;
const bool true = 1;
const bool false = 0;
这种方法不错,但是不允许重载bool:
//file f.h
void f(int); //ok
void f(bool); //ok
//file f.cpp
void f(int){/*...*/} //ok
void f(bool){/*...*/} //error,重定义
另一个问题跟选择这种方法会产生不可预料的结果:
void f(bool b)
{
assert(b != true && b != false);
}
第二种方法:#define(评价:0/10)
这种方法一般原型:#define bool <something>,典型如下:
#define bool int
#define true 1
#define false 0
这种方法有害的:这不仅仅与上面第一种方法有相同的问题,而且通常破坏了#define,例如:当有人试图使用这个库,而它已经有一个命名为false的变量,现在false同内置类型表现就会不太一样。
尝试使用预处理程序模仿一个类型是一个不太好的注意。
第三种方法:enum(评价:9/10)
原型如:enum bool,典型如下:
enum bool{false,true};
这种方法比第一种方法好些,它允许重载,但是它不允许从一个表达式自动转换成枚举:
bool b;
b = (i == j);
这里错误的:因为int不能隐式转换成enums。
第四种方法:class(评价:9/10)
这种是面向对象语言,所以写一个类如下:
class bool
{
public:
bool();
bool(int); //在条件允许下转换
bool operator =(int);
//operator int(); //有问题
//operator void*(); //有问题
private:
unsigned char b_;
};
const bool true(1);
const bool false(0);
除了转换操作有问题外,其他都可以正确工作:
- 由于自动类型转换,bool重载解决了冲突(尤其是基本类型转换)
- 如果使用自动类型转换,bool型的数据会影响函数重载,就像其他任何一个类的隐式构造和自动类型转换一样。
- 不能转换为int和void*,bool对象在条件表达式测试无法“自然”的测试。
- 如果不使用自动转换,那么bool类型将无法使用条件测试:
bool b;
/*...*/
if(b) //错误,不能转换为int或void*相似的类型
{
/*...*/
}
这是一个经典所谓的Catch-22困境:我们必须也只能选择其中一种,但没有任何一种可以满足我们所有的需要——使得这个类表现的像一个基本类型bool一样。
总结:
- typedef ... bool 不允许重载。
- #define bool 不允许重载且通常破坏了#define
- enum bool允许重载但在条件测试下不能进行自动转换(类似b = (i== j);)。
- bool类允许重载但不能让bool在条件中测试,除非它能提供自动转换为基类类型,可它通常破坏了自动转换。