Conversations: Value Lessons(值类型)
Jim Hyslop&Herb Sutter /著
刘未鹏 /译
什么时候你才能学会重视先知的忠告?判断你定义的是什么类型的对象并且始终不渝。
某天,Bob正和往常一样... ,而Kerry,可怜的实习生,每当Guru经过时总会陷入一种神经质的紧张,网络挂了,Wendy——每当这种时候能够找到的唯一神志还算清醒的人——却正在度假。有时候你会发现,起床真不划算。
Kerry和我正在他的桌子旁,检查他写的一些代码。我惊讶于代码的质量——几乎找不出需要我指点的地方(不过可以肯定的是,在这些代码被check in后Guru肯定会发现问题)。
“问题出在这一段代码”他说:
Ff original;
// ...
{
Ff tempFF(original);
// ...
}
“当对象的拷贝被摧毁后,原来的那个对象却出问题了。”
我看了一会儿代码,忽然有一种预感——我找到Ff的定义:
class Ff
{
T t;
public:
Ff() : pointer( 0 ) {}
~Ff() { delete pointer; }
U *pointer;
void f();
void g();
};
“啊哈,你的问题出在这里——你违反了‘三大定律(The Law of the Big Three)’”我把自己重新放回了椅子上。
“三...,那是Guru杜撰出来的玩意儿?”
“不是,”我微笑着“‘三大定律’出自Marshall Cline的C++ FAQ。说的是:如果你有了拷贝构造函数,赋值操作符或析构函数中的任何一个,那么你通常都需要它们三个。现在,把拷贝构造函数和赋值操作符加上去,进行正确的深拷贝,问题就解决了。”
“OK”。
突然,一个声音把我们吓了一跳,Kerry的椅子叫得几乎和Kerry一样大声。
“早上好,师傅”,我很快反应过来,Kerry把他的椅子从我旁边挪开了一点。
“这些讨厌的东西是什么?”她指着屏幕上的类定义。
“呃,没...没什么...”我结结巴巴的说,在她的语气下不寒而栗,“他正准备要加入拷贝构...”
“‘三大定律’是小事,我指的是那个肮脏的public数据成员”我的心沉了下去——我怎么会把如此明显的东西给忘了呢?
“啊哈,好吧...”Kerry叫出声来“我在...呃,某些地方...读到过,对于值类型,public数据成员没有问题”。我感到吃惊——我们的小老鼠正学会如何咆哮。Guru冷静的看了他一会儿。
“我认为,我的学徒工”最后她开腔了,更加冷静(我松了口气)“你把值类型和POD类型搞混淆了,从定义上说,POD不能拥有non-public,non-static数据成员。你的类包含了一个private数据成员,所以它不是POD类型。但是留意——一个类要么是值类型,要么是对象类型。所以,你创造了一个‘四不象’!”
“呃...你所说的‘值类型’和‘对象类型’是指...?”我询问道,对于Kerry知道一些我不知道的东西感到有点恼火。
“一个值类型依赖于它的状态,而并非行为”Guru轻轻的说,把一缕灰白的头发拢到脑后,“而一个对象类型则更多的依赖于它的行为和身份,而并非状态。”
“啊哈,我明白了”我答道,同时祈祷Guru没有识穿我假装明白的样子。
Guru面无表情的看了我一会儿。(有时候你会发现真的不值得起床)。“我的学徒工,难道你忘了先知Booch的话?这些在他的大部头中都有优雅的叙述”。
“对,当然,”我掷地有声的说“一个对象的状态是...呃...是它的所有数据成员的当前值,对吗?”
“本质上是这样,Booch还开导我们说,一个对象的状态是对该对象施加累计操作后的结果。”
“那么一个值类型又该如何强调它的状态呢?”
“值类型的成员函数着重于操纵以及表现对象的状态。通常,值类型的例子有string,date等等。先知Henney教导我们,具有相同状态的值类型可以相互替代。他还精化了对象类型的分类学,加入了实体(Entities),服务(Services)以及任务(Tasks)。”
“那么,也就是说,这个类得把它的public数据隐藏起来——把它隐藏在Get和Set函数后面如何?”
这句话为我招来了一个白眼。我真希望可以回到被窝里去。
“我的学徒工,看起来假期的野味让你变得愚蠢了。我是不是还说过你必须得判断你的类“是驴还是马”?Get和Set成员函数绝大部分时候是对值类型用的。考虑std::string,它是值类型,其Get函数被命名为c_str()”。
“f()和g()这些函数包含在整个对象的行为中”她指着显示器说“并且对对象内部的状态没有给出任何暗示。这就表示该类是一个对象类型。另一方面,Get和Set函数却表现了成员数据pointer的状态,这又表示该类是个值类型。”
“但是,”Kerry插进来说“现实中情况肯定没有那么清楚,不是吗?”
“不要叫我Shirley”Guru面无表情的说,“是的,我的学徒工,设计抉择并非总是那么明显。事实上,大师Ubilab承认值通常会以对象的形式来实现。我有些怀疑这是由于,呃,值类型的价值在OO社区被很大程度上忽视了的缘故。在你的代码中,你拥有一个对象,而它的行为却试图去接近一个值类型”。
“对于值类型,还有一个我忘了提醒的地方。通常,拷贝对象类型(的对象)是没有任何意义的,这是因为它们具有很强的唯一性。考虑一个Employee类——如果有两个Employee的名字都是Bob会引起什么样的灾难”
我为这个想法感到不寒而栗。Guru转过身,悄悄走开了。Kerry把目光转向我。
“不要叫我Shirley?”他的脸厌恶地扭曲着。
“现在你知道她只是个程序员,而并非喜剧演员了吧”我说。
分享到:
相关推荐
techies-conversations:工业化与工业化
Conversations 是适用于 Android 的开源 Jabber/XMPP 客户端,旨在提供独特且更自由的移动消息传递体验。 XMPP 是一种联合协议,可以与所有 XMPP 服务器配合使用,让您可以自由地为自己选择值得信赖的服务器,同时...
发送和接收图像以及其他类型的文件 通过外部分享您的位置 当您的联系人阅读您的消息时的指示 遵循 Android 设计指南的直观 UI 联系人的图片/头像 与桌面客户端同步 会议(支持书签) 地址簿集成 多账户/统一收件箱...
发送和接收图像以及其他类型的文件 分享你的位置 发送语音留言 联系人已读邮件时的提示 遵循Android设计指南的直观UI 图片/联系人头像 与桌面客户端同步 会议(支持书签) 通讯录整合 多个帐户/统一收件箱 对电池...
自述 此自述文件通常会记录启动和运行应用程序所需的任何步骤。 您可能想要涵盖的内容: Ruby版系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列、缓存服务器、搜索引擎等) 部署说明… 如果您不...
Conversations: the very last word in instant messaging Design principles Be as beautiful and easy to use as possible without sacrificing security or privacy Rely on existing, well established ...
什么一组转换器脚本,用于生成有关围绕自由图形的工具和实践的对话的打印集合。对话 如何mdsh2tex2pdf.sh 是转换器实用程序,用于从某个位置(本地/远程)提取 mdsh 代码,并使用 LaTeX 代码作为中间格式从此内容...
Conversations是Android的开源Jabber / XMPP客户端,旨在提供独特且更自由的移动消息传递体验。 XMPP是一种联合协议,可以与那里的每台XMPP服务器一起使用,使您可以自由选择自己可信赖的服务器,同时仍然可以与其他...
会话中很棒的情感识别有关与会话中的情感识别(ERC),上下文情感/情感/讽刺分析或语用学的共同分类(如会话中的对话行为)相关的论文的综合阅读清单。 如果列表中缺少任何新的或现有的纸张,请随时发送PR。...
雷鸟对话 此扩展改进了Thunderbird中电子邮件的主题摘要。 通过包含来自GMail的一些想法,它极大地改善了UI。 进一步来说: 您自己的消息显示在线程中, 您最初会看到摘要,可以将其展开以显示完整的消息, ...
ME525--文本信息(进程:com.motorola.conversations)意外停止解决方法
Bot_conversations_history:对话记录
SUNET: Speaker-utterance interaction Graph Neural Network for Emotion Recognition in Conversations
Android-Conversations.zip,conversations是android平台的开源xmpp/jabber客户端,安卓系统是谷歌在2008年设计和制造的。操作系统主要写在爪哇,C和C 的核心组件。它是在linux内核之上构建的,具有安全性优势。
联系英语听力的高级听力课程:Understand FAST English Conversations
Topical-Chat: Towards Knowledge-Grounded Open-Domain Conversations
对话服务器 对话 API 服务器
Conversations,conversations是android平台的开源xmpp/jabber客户端.zip
Conversations - Mocap Animation Pack