📄 6154.htm
字号:
<HTML>
<HEAD>
<meta http-equiv='Content-Type' content='text/html; charset=gb2312'>
<style >
.fst{padding:0px 15px;width:770px;border-left:0px solid #000000;border-right:0px solid #000000}
.fstdiv3 img{border:0px;border-right:8px solid #eeeecc;border-top:6px solid #eeeecc}
</style>
<title>
Guru of the week #26 Bool.
</title>
</HEAD>
<BODY>
<center>
<div align=center><div class=fst align=left><div class=fstdiv3 id=print2>
<p><font SIZE="1" COLOR="#000000">
</font><font color="#000000" size="4"><b>Guru of the week #26 Bool.</b></font></p>
<p>作者:hub sutter<br>译者:黄森堂<br>感谢ed9er(始祖鸟)的校验。</p>
<p>/*此文是译者出于自娱翻译的gotw(guru of the week)系列文章第一篇,原文的版权是属于hub sutter(著名的c++专家,《exceptional c++》的作者)。此文的翻译没有征得原作者的同意,只供学习讨论。——译者<br>*/</p>
<p><font color=#0000ff size=4><b>#26 bool.</b></font></p>
<p><b>难度:</b>7/10</p>
<p>我们有需要基本的bool类型吗?,现存的语言为什么不是仅仅的仿真它,本期将给你答案。</p>
<p><b>问题:</b></p>
<p>自从arm.[1]发布以来,除了wchar_t之外(wchar_t在c里是用typedef实现的),bool是唯一添加到c++里的基本数据类型;如果不添加这个基本类型,能用已有的数据类型达到相同的效果吗?如果能,请给出一个实现,如果不能,请指出各种可能的实现方法都有哪些缺陷?</p>
<p><b>解决方法:</b></p>
<p><font color=#999933>自从arm.[1]发布以来,除了wchar_t之外(wchar_t在c里是用typedef实现的),bool是唯一添加到c++里的基本数据类型;如果不添加这个基本类型,能用已有的数据类型达到相同的效果吗?如果能,请给出一个实现,如果不能,请指出各种可能的实现方法都有哪些缺陷?</font></p>
<p>回答是:不能,bool明确地添加到c++作为基本类型(并保留true与false关键字),因为它们(bool型和true, false)没法通过现有的语言特性准确实现。</p>
<p><font color=#999933>如果不是,将给出同等实现基本类型的几个潜在的原因。</font></p>
<p>4种主要的实现方法:</p>
<h4>第一种:typedef(评价:8.5/10)</h4>
<h4>option 1: typedef (score: 8.5 / 10)</h4>
<p>这种方法用"typedef <something> bool;",典型如:</p><pre> typedef int bool;
const bool true = 1;
const bool false = 0;</pre><pre>这种解决方法不错,但是不允许重载bool,例如:</pre><pre> // file f.h
void f( int ); // ok
void f( bool ); // ok, 重新声明相同的函数
// file f.cpp
void f( int ) { /*...*/ } // ok
void f( bool ) { /*...*/ } // error, 重定义</pre><pre>另一个问题是跟这相同的代码:</pre><pre> void f( bool b ) {
assert( b != true && b != false );
}</pre>
<p>于是可以看出第一种实现不够好!</p>
<h4>第二种方法:#define(评价:0/10)</h4>
<p>这种方法用"#define bool <something>",典型如:</p><pre> #define bool int
#define true 1
#define false 0</pre>
<p>这种方法是有害的,这不仅仅与上面的第一种方法有相同的问题,而且通常破坏了#defines,例如:它缺乏自定义,且当有人在尝试使用这个库时已经有了变量名字'false';现在就可以从基本类型看到它们的差异。</p>
<p>尝试用预处理程序来模拟这种类型是很坏的主意。</p>
<h4>第三种方法:enum(评价:9/10)</h4>
<p>用这种方法去产生"enum bool",典型如:</p><pre> enum bool { false, true };</pre>
<p>这种方法比第一种方法好几分,在这种方法,它允许重载(第一种方法的主要问题),但在条件表达式不允许自动类型转换(第一种方法是可以的):</p><pre> bool b;
b = ( i == j );</pre>
<p>这是错误的,因为int不能隐含地转换成enums</p>
<h4>第四种方法:class(评价:9/10)</h4>
<p>这是面向对象语言,对吗?,所以为什么不写个类,典型如:</p><pre> class bool {
public:
bool();
bool( int ); // 在条件表达式允许转达换
operator=( int ); //
//operator int(); // 有问题!
//operator void*(); // 有问题!
private:
unsigned char b_;
};
const bool true ( 1 );
const bool false( 0 );</pre>
<p>除了转换操作有问题之外就可以工作了,这些问题的原因:</p>
<p>1.由于自动类型转达换,重载解决了bool的冲突,(尤其是基本类型的转换)</p>
<p>1. 如果使用自动类型转换,bool型的数据会影响到函数重载,就像其他任何一个类里的隐式构造函数和(或)自动类型转换一样(尤其是基本类型的转换)。</p>
<p>2.不能转换与int或void*相似的类型,bool在条件中不能作测试,例如:</p>2. 如果不使用自动类型转换,那么bool类型将无法使用在条件判断中 <pre> bool b;
/*...*/
if( b ) // 错误,不能转换与int或void*相似的类型
{ //
/*...*/
}</pre>
<p>这种方法抓住了22种情形:我们必须选择一个或其它的,两种方法皆让我们</p>
<p>这是一个经典的所谓的catch-22困境:我们必须也只能选择其中的一个,但没有一种情况可以满足我们的需要:使这个类表现得和基本类型bool一样。</p>
<h4>总结:</h4>
<p>a typedef ... bool不允许重载。</p>
<p>a #define bool不允许重载且通常破坏了#define</p>
<p>enum bool允许重载但在条件表达式不能进行自动类型转换(相似于"b = (i == j);")。</p>
<p>bool类允许重载但不能让bool对象在条件中作测试,除非它能提供自动转换到基本类型,可它通常以破坏了类型自动转换。</p>
<p>对极了,我们真的很需要基本成的bool类型,最后,还有一件事情(和重载有关的),就是,对于所有的方式(除了在第四种方式下有可能)我们都无法指明那个条件判断表达式是一个bool类型。(我想作者要表达的意思是,对于各种模拟bool的方式,我们都无法把bool当作一种真正意义上的数据类型,并使用它来重载函数,考虑这样的调用:func(i == j); 在被当作参数去寻找匹配的函数之前,你根本无法改变这个条件判断表达式运算的结果的类型,其实我觉得关于这点他在前面已经讲得很清楚了,不知道为什么要称作one more thing)</p>
</DIV></div></div>
</center></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -