C_and_CPP 版 (精华区)
发信人: seaboy (浪小), 信区: C_and_CPP
标 题: A Midsummer Night’s Madness
发信站: 哈工大紫丁香 (2003年06月23日08:39:01 星期一), 站内信件
A Midsummer Night’s Madness
taodm翻译
-------------------------------------------------------------------------------
-
“嗯,说吧,你有一小会儿时间?”
我辨认出了从我身后传来的胆小的声音。Kerry,我们部门的新员工,正贴着我的房间站着
。他是够聪明的,但……男人,有些搞笑。我曾经这么告诉温迪,但是她只是喃喃自语,
大概是有关盆和壶的问题。
“是的,没问题,”我转向他。在Kerry从事的方面我并没有更多的经验,但是被当作老手
使人觉得舒服。 我准备着他把什么都丢给我。
“我们伦敦办公室的热线号码是什么?”
我叹了口气。成为指导专家真麻烦。我在便笺上写下号码交给他。
“谢谢,”他一边转身一边说着。“我必须问鲍伯一些事情。”
危险,罗宾森!我的心都提到嗓子眼了。“别!”我脱口而出。
Kerry楞住了。“那是说,别打扰他?”“我的意思是,嗯,”飞快地想着……飞快地想着
。“别打扰他。我确信定我们能处理。”
“但鲍伯说我应该离你远点,”Kerry结结巴巴地说道。“他离开前说过,如果我有任何问
题,应该打电话给他。他说,'无论你做什么,可千万别……'”
“哦,看一下时间,”我打断道。“伦敦时间现在已经过了下班时间了。鲍伯应该已经离
开很久了。”
“但是那里现在才3:30。”
“是的,这是鲍伯的下班时间,我认为。”我大声说道,“鲍伯……当他在伦敦的时候,
工作时间变早了。”
“哦。好吧,我想这有道理,”Kerry看起来不太确信,但是他还是坐在我的访客椅上。
“问题是,我有一个接收指标类型的参数的函数,”他边说边在白板上写着:
typedef T* Tptr;
void f( const Tptr t)
{
*t = T(); // don't want this, but it's allowed
}
“在函数体里,我能修改t,即使我申明它为const 。我也尝试了Tptr const t ,但是它
也不起作用。如果我不使用typedef,我知道,我可以写 const T * t,那才是我想要的。
”
“啊,”我想了一下。我知道我以前也遇到过这个问题。
但在哪里?什么时间?“嗯,typedef和宏的文本替换不完全一致。我记不清所有细节了,
但我确定,在类型后面加const修饰字时,其行为和你的期望相同。”我稍微地修改了一下
代码:
void f( Tptr const t ) // still means T* const
Kerry瞄着新代码。“但是Tptr const t和const Tptr t并不相同。不是吗?”
一个新的声音说:“不!没有不同。”
我为身后Guru的声音所振动。Kerry尖叫着从椅子上跳起来。Guru平静地继续着,合上手中
的厚书,对我们的反应视而不见:“告诉我,年轻人, int const i和const int i之间有
什么不同?”
Kerry的眼睛睁得很大-非常大,以致于我很好奇于鲍伯对他怎么描述Guru的。Guru则似乎
没有注意到他的发抖。
我认为现在最好别参与Guru的行为:“他们是相同的事物。难道不是吗,Kerry?”我提示
道。Kerry只是点点头,没说话。
Guru皱了一下眉头。“那么,如果const int和int const是等价的,却期望Tptr const和c
onst Tptr不同,你是这么认为的吧? 嗯?而你不该这么认为的。”
“是的,我正在解释那个部份,”我插了一句嘴。“好吧,Kerry,在这个码中,什么东西
是const的?”我写道:
const int i; // or int const i;
“int,”Kerry慢慢说道。这个简单的问题让他恢复了平静。
“好的,”我点头。“现在在这个码中,const的是什么,即使T是个typedef?”我写着:
const T t; // or T const t
“T对象,”Kerry答道,现在比较有自信了。
“好的。现在在这个码中, const的是什么?”我又写:
const Tptr t; // or Tptr const t
“那个……”Kerry吞吞吐吐的。“哦。Tptr?”
“对。但是Tptr表现为一个复合类型,而const只是此类型的一部份。指针本身是const的
;这和T* const相同。现在,有多了一点点:在这个码中,什么是const的?”我写着:
const T* t; // or T const* t
“那个……所指向的对象,”他叫了出来。
“对,”我肯定道,并放下书写笔。“这就是const Tptr和 const T*之间的区别。”
Guru把一只手搭在我肩上,又接过话题:“实际上,这是一些先知[1]作以下建议的原因之
一:在不改变申明的含义的前提下,将const关键字放在尽可能右边。然后你在心里将type
def作为邪恶的宏展开,”她顿了一下,“以得到正确的含义。”
“是的,但是我总觉得比较拗口,”我抱怨道。“我喜欢申明'const int * iptr',这样
当我读它时,我可以念为'常量的int型指针iptr' 。几乎每个人和所有的书,都是这么写
它的。另外那种方法感觉比较拗口。”
“拗口?”Guru扬起眉毛。“虽然我们既不推荐也不反对'const在右侧'的风格,但这样做
确实有些好处的。它能使得读申明语句比较容易。”
“如何?”Kerry问。
“用编译器使用的方式来读它,你必须这么做。你其实正在的说是'iptr是一个指向const
的int的指针', 从右向到左才是'int const * iptr;'的真实含义。”
“但是,那么,我如何申明我的函数以使得T对象真的是const的?”Kerry回到他的最初问
题上。
“啊,我的孩子,很简单。”Guru写道:
void f( const T* t )
“但是我真的想要使用typedef,”Kerry反对。
“啊,擦板。如果一定要用typedef,为所需的const T另外定义一个typedef:”
typedef const T* Tcptr;
void f( Tcptr t )
“但仍然要小心,”Guru的话预示着恶兆,“我们已经发现简单地使用typedef来产生一个
指针价值非常小。由于我们这里讨论的const缺陷,必须提供两个分开的typedef。这样的t
ypedef增生,而又在意义上区别非常小,只会是造成混乱。也就没什么价值可言。”
Guru又打开她的书,转身离开了。“混乱是编程的黑暗面。太多的typedef,无力的命名-
这些都导致……”她的声音伴随着身影消失于某个拐角。
我看了一下Kerry。他盯着我,欲言又止。
“别烦恼,”我安慰他说,“你会习惯她的。她真的是一个极其优秀的程序员。”Kerry眨
着眼,张开嘴又闭上,一脸茫然地走开了。我耸耸肩,又回去干活。
-------------------------------------------------------------------------------
-
[注释]
[1] Notably Dan Saks.
--
欢迎到C_and_CPP版讨论相关问题。
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.239.80]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.869毫秒