条款45:GotW#26 Bool

本文探讨了C++中bool类型的必要性,并分析了通过typedef、#define、enum及class等四种方式模拟bool类型的可行性和局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题】

除了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在条件中测试,除非它能提供自动转换为基类类型,可它通常破坏了自动转换。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值