分享
 
 
 

对话:#13: 怎样持久化一个对象

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

[声明]:本英文资料源自于Herb Sutter 创建的“Conversation”栏目,“C++ 翻译小组”的翻译作品供学习交流与参考用途,不得用于任何商业用途。未经Herb Sutter、Jim Hyslop同意,不得转载;对于违反以上条款,翻译小组对此不负任何责任;特此声明。

文章来源:http://www.gotw.ca

版权归属:Herb Sutter and Jim Hyslop

译 者:徐波

对话:#13: 怎样持久化一个对象[1]

当我疲惫地穿过走廊时,正是欧洲当地时间零点十分。我已经筋疲力尽,又有三个下午的值班在等着我。

一小束柔和的光散发到凉爽的金属走廊上。梅杰.吉尔伯的房门微开着,我想这是巧合,尽管通风系统最近工作负荷太重很可能也是一个原因。更巧合的是,科洛纳正在梅杰的办公室与梅杰会谈,而不是相反。

另一方面,我听见里面正好有低语声肯定不是巧合,我慢下脚步,凝神细听。通风机时而呜咽时而喘气的响声使我的旁听显得很困难,但也使他们没有意识到我的到来。

“我…,但那些人实在是固执透了,”另一个声音说道,我后来才听出是科洛纳。

然后是一阵沉默,接着吉尔伯的声音又响了起来:“那么他们还在路上?有多少?什么时候到达?”

“至少有六船,”稍停片刻,“给他们一个月,联合国必须能够控制住局势,直到我们讨论出决定采用什么技术,不管多长时间。”

一阵大笑,肯定是吉尔伯:“联合国?你说的是那个所谓的国家联盟?”

“它们都一样。亚洲人很固执,我们不得不给他们泄泄气。”

- - - - - - - - - - - - - - - - - - - - - - - - -

“你知不知道,小伙子,你后来看上去有些分心,”温迪一边把wasabi拌到豆酱里,以用作寿司馅,一边说道,“一切都搞定了吗?”

我出神地盯着手上那根加利福尼亚春卷,约一分钟后,“是安娜,”我承认,“自从我知道她是鲍勃的女儿后,我就开始回避她。她隔不多久就呼我,但我都不回。我把她的电话号码从我的PDA中删除了,我喜欢她,但我不知道我能不能处理…”

“安娜上周末在我的婴儿浴室,”温迪善解人意地点点头,“她确实很喜欢你。”她见我没吭声,又接着说:“我想告诉你我对她说了些什么。我刚认识我丈夫的时候,当时我常常加班加得很晚。那家公司是属于很注重必须按时完工的那种,你知道吗?总之,汤姆常常约我出去,我也很想这样,但我经常不得不加班。最后,我决定协调好时间。接下来的事,正如他们所说,都已成了历史。汤姆从不放弃,所以我告诉安娜也不要气馁。坚持(persistence)就是胜利。”

“得了,不要跟我说persistence!”我心烦意乱地说道。

温迪眨了眨眼,“嗯?”

“哦,”我摇了摇头,“我正试图在我的类层次结构中实现一些简单的对象persistence。我还没有想出该怎么来做。我请教Guru,可她说我该知道的她都已教给了我。我真的想不出是怎么回事。”

温迪抿了抿唇,稍思片刻,“我们曾有协定,午饭期间不谈工作,今天就破一下例吧。你说得详细一点。”

“我知道其实并不太难,”我嘴里含着一大口饭,说道,“每次当我开始干时,我知道我能搞定。主应用程序能够实例化派生类。我需要把那个类写到ostream,也没问题。但当我想把它读回,再重新构造成正确的类时,就遇到麻烦了。”

“Guru没说错,你该知道的确实已经知道了。你怎么来创建对象呢?不到运行时刻你并不知道对象的确切类型啊?”

“使用类工厂(class factory)。”我说。

“不错,就象你上个月[2]所实现的那个一样。现在,你给类工厂传递什么东西来获得合适的类型?”

“一些标志。我用了std::string。”

“好,那你是从哪里取得那些标志的呢?”

“嗯……是这样,总不会是凭空捏造的,我想是从文件中读取的吧。”就在些时,我突发灵感,“对,就是这样。当我写出对象时,我首先写出一些标志,标明该对象的确切类型,接着再写入对象的信息。在重新构建对象时,读取这些标志-将它传递给类工厂-从文件流读入,这些都是很简单的呀。”

“对,”温迪回答说,“如果你想干得漂亮一点,你可以……”

“保留这些标志!”我作了个暂停的手势,“谢谢你帮助我清理混乱的思路。现在很清楚了,我想重新遵守我们之间‘午餐期间不谈正事’的协定。”我开始细心品味那道主菜。

稍后,当温迪和我回到办公室时,我坐在计算机旁,相当轻松就整理出基类:

class Base

{

private:

// … 一些数据,与本主题无关 …

virtual std::string classID() const { return "Base"; }

protected:

// 当派生类装入自身后,应该调用该函数的父类实现。

virtual void do_read( std::istream& );

// 当派生类保存完自身后,应该调用该函数的父类实现。

virtual void do_write( std::ostream& ) const;

public:

// … 需要实现的一些虚拟函数,与本主题无关…

// Streaming functions.

void read( std::istream& );

void write( std::ostream& ) const;

virtual ~Base();

};

// 流处理过程中的几个帮助函数。注意它们并非友元!

std::ostream& operator <<

( std::ostream& o, const Base& b) { b.write(o); }

std::istream& operator >>

( std::istream& o, Base& b) { b.read(o); }

// [3]

“很好,我的孩子,”Guru的声音又在我的身后响起。我从椅子上蹦了起来,责怪自己怎会没有想到她的来访。她接着说:“把你的成果简单地跟我说说。”

“很简单,”等Guru坐到客椅上,我回答说,“通过重载的<<操作符,Base::write会被调用,这里是它的实现:”

void Base::write( std::ostream& o ) const

{

o << classID() << std::endl;

do_write(o);

}

“嗯,模板方法模式(Template Tethod pattern),”Guru点点头,“你真聪明,我的孩子[4]。”

“实现也相当简单,”我继续说,“简单地写出类标识符,接着触发do_write虚拟函数。do_write函数负责处理那些把对象信息写入流的细节。每个派生类必须调用其父类的do_write函数。不过,读入要稍微复杂一些。”我打开那个用于封装读入的函数:

std::auto_ptr<Base> loadBase( std::istream& inFile )

{

std::string className;

std::getline( inFile, className );

std::auto_ptr<Base> newBase =genericFactory<Base>::instance().create(className);

if( newBase.get() != 0 ) {

inFile >> *newBase;

}

return newBase;

}

“这是一个三步骤的过程。首先,我从文件中取得类的ID。接着,我用这个ID从类工厂中得到一个新对象。最后,我通过read函数,重新构建类的数据:”

void Base::read( std::istream& i )

{

do_read(i);

}

“这里我也用了模板方法模式,但对于这样的简单函数,有点牛刀杀鸡的感觉。当然,do_read负责处理读入和确认信息等麻烦活。派生类的do_read应当调用其父类的do_read函数。”

“干得好,我的孩子,”Guru起身说道。

“请稍候,”我脱口而出,Guru停住脚步。“告诉安娜,我丢了她的电话号码,不过我今晚在家,她可以打电话给我。”Guru点点头,转身离去。

- - - - - - - - - - - - - - - - - - - - - - - - -

“‘泄气’,哈。”又是吉尔伯的声音。我眨眨眼,摇摇头,努力驱赶袭上心头的睡意。“他们知道些什么?”

“我想不会太多,那些亚洲人似乎怀疑到什么。”

“他们难道不相信我们的掩饰说法?我们对他们说的是由于通信故障,正好切断了他们与其同胞的通话。”吉尔伯的声音明显带有讽刺的味道。

“他们有所怀疑,”另一个声音重复道,“他们正过来呢,我们要处理好这事。目前为止你的技术队伍发现了什么?”

站在走廊上,我越来越困,不想再听下去了。舒舒服服睡一晚也还来得及。

[感谢]

我们要感谢Andrei Alexandrescu,他提出了一个虽然不大但很重要的问题,就是我们以前文章中的命名问题。我们错误地将GoF(“Gang of Four”(四人帮),即《设计模式》的四位作者)的“Factory Method”设计模式称为“Abstract Factory”模式。这些模式在Andrei的著作《Modern C++ Design》(Addison-Wesley,2001)中都有专门的一章来讲述。对可能引起的混淆,我们表示歉意。

[注释]

[1]可按“How to Handle a Woman”(Camlot, Lerner和Loewe)的调子来唱。

[2] Jim Hyslop和Herb Sutter. "Conversations: A Factory, Template Style," C/C++ Users Journal C++ Experts Forum, 2001年7月, www.cuj.com/experts/1906/hyslop.htm.

[3]可到hyslop.zip下载完整的可工作的例子程序。

[4] E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1995).中文名《设计模式》

[关于作者]

Herb Sutter

是个独立顾问,也是ISO/ANSI C++标准委员会的秘书。你可通过hsutter@acm.org.联系他

Jim Hyslop

Leitch Technology International Inc.资深的软件设计师,你可通过jim.hyslop@leitch.com联系他

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有