📄 20000916026.htm
字号:
<HTML>
<HEAD>
<TITLE>在 C++Builder 中,如何简化基本数据类型的流操作 ?</TITLE>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR>
</HEAD>
<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0
vLink=#990099>
<div align="center">
<table width="744" border="0" cellspacing="0" cellpadding="0" height="76">
<tr>
<td>
<p align="center"><font size="3"><br>
<b>在 C++Builder 中,如何简化基本数据类型的流操作 ?</b></font></p>
<div align="left">
<p><font color=#000000>如何简化基本数据类型的流i/o操作? 即怎样将整数/浮点数/字符型等数据类型的流操作用同一种代码书写出来
? </font> </p>
<hr noShade size=1 width="100%">
描述:程序中可能需要将某个类的实例对象存入流中,而该类中可能包含有各种类型的对象, 如:整数/浮点数/字符型等,粗心大意的写法可能如下:<br>
void TSomeClass::SaveToStream(TStream *stream)<br>
{<br>
<dir>stream->WriteBuffer(this,sizeof(*this));<br>
</dir>
}<br>
很明显,以上写法的弊端很多,如不能支持虚函数、类的版本识别及指针型的动态对象, 为此,我们通常会将该类中每个对象分别进行流操作,可提供更多的灵活性,
但这样书写的代码较长,显得很烦琐。比如:<br>
void TSomeClass::SaveToStream(TStream *stream)<br>
{<br>
<dir>stream->WriteBuffer(&count,sizeof(count));<br>
stream->WriteBuffer(&num,sizeof(num));<br>
other->SaveToStream(stream);<br>
//其它存储代码....<br>
</dir>
}<br>
既然如此,有没有办法可将以上代码作些简化呢?
<p><font color=#000000> </font> </p>
<p>实际上,这个问题就是怎样将整数/浮点数/字符型等数据类型的流操作用同一种代码书写出来 ? 很明显,都会想起使用类模板来构造类。一个通用的类构造如下:
<p>template < class T > class TDataIO<br>
{<br>
<dir>private:<br>
T d;<br>
public:<br>
TDataIO(T d){this->d=d;}<br>
TDataIO(void){ ; }<br>
protected:<br>
T SaveToStream(TStream*stream)<br>
{stream->WriteBuffer(&d,sizeof(T));return d;}<br>
T LoadFromStream(TStream*stream)<br>
{stream->ReadBuffer(&d,sizeof(T));return d;}<br>
public:<br>
T operator>>(TStream*stream)<br>
{return SaveToStream(stream);}<br>
T operator<<(TStream*stream)<br>
{return LoadFromStream(stream);}<br>
</dir>
};
<p>利用以上类,便可直接写出如下代码:<br>
<dir>TDataIO< int > ( num ) >> stream; //将num作为int型存储<br>
TDataIO< double > ( sum ) >> stream; //将sum作为double型存储<br>
int n = TDataIO< int > ( ) << stream; //从流中读取一个整数赋给n<br>
double d = TDataIO< double > ( ) << stream; //从流中读取一个浮点数给d<br>
</dir>
当然,对常用的构造类还可作进一步具体化的,比如可定义以下具体流类:<br>
<dir>typedef TDataIO < char > TChar;<br>
typedef TDataIO < bool > TBool;<br>
typedef TDataIO < int > TInt;<br>
typedef TDataIO < double > TDouble;<br>
</dir>
替换以上具体的类定义,流操作代码便可进一步简化书写:<br>
<dir>TInt ( num ) >> stream; //将num作为int型存储<br>
TDouble ( sum ) >> stream; //将sum作为double型存储<br>
int n = TInt ( ) << stream; //从流中读取一个整数赋给n<br>
double d = TDouble ( ) << stream; //从流中读取一个浮点数给d<br>
</dir>
<hr noShade size=1 width="100%">
<p>很显然,以上类模板(TDataIO)还可以适应定长的构造类型(struct/class), 但构造类型中不能包含指针对象和虚函数,否则在读取操作之后,
相应对象的多态性和指针对象的存取将会导致意料不到的后果! 如果它已经在运行了,那可惨了! 赶紧选择(Run|Program Reset)命令吧。
<p>难道这个类模板的功能如此差劲,被这么个小问题都搞得死去活来 ? 还好,天无绝人之路,对于构造类型,可以使用以上类模板对指针对象分别进行处理,
同样能save/load构造类型中的指针对象,同时还可消除虚函数对流操作的影响, 此外,还可对流类的版本控制带来直接的益处,请参见“<a
href="20000916020.htm">流类的版本控制</a>”。
</div>
</td>
</tr>
</table>
</div>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -