|
如何简化基本数据类型的流i/o操作? 即怎样将整数/浮点数/字符型等数据类型的流操作用同一种代码书写出来 ? 描述:程序中可能需要将某个类的实例对象存入流中,而该类中可能包含有各种类型的对象, 如:整数/浮点数/字符型等,粗心大意的写法可能如下: void TSomeClass::SaveToStream(TStream *stream) { 很明显,以上写法的弊端很多,如不能支持虚函数、类的版本识别及指针型的动态对象, 为此,我们通常会将该类中每个对象分别进行流操作,可提供更多的灵活性, 但这样书写的代码较长,显得很烦琐。比如: void TSomeClass::SaveToStream(TStream *stream) { stream->WriteBuffer(&num,sizeof(num)); other->SaveToStream(stream); //其它存储代码.... 既然如此,有没有办法可将以上代码作些简化呢?
实际上,这个问题就是怎样将整数/浮点数/字符型等数据类型的流操作用同一种代码书写出来 ? 很明显,都会想起使用类模板来构造类。一个通用的类构造如下: template < class T > class TDataIO T d; public: TDataIO(T d){this->d=d;} TDataIO(void){ ; } protected: T SaveToStream(TStream*stream) {stream->WriteBuffer(&d,sizeof(T));return d;} T LoadFromStream(TStream*stream) {stream->ReadBuffer(&d,sizeof(T));return d;} public: T operator>>(TStream*stream) {return SaveToStream(stream);} T operator<<(TStream*stream) {return LoadFromStream(stream);} 利用以上类,便可直接写出如下代码: TDataIO< double > ( sum ) >> stream; //将sum作为double型存储 int n = TDataIO< int > ( ) << stream; //从流中读取一个整数赋给n double d = TDataIO< double > ( ) << stream; //从流中读取一个浮点数给d typedef TDataIO < bool > TBool; typedef TDataIO < int > TInt; typedef TDataIO < double > TDouble; TDouble ( sum ) >> stream; //将sum作为double型存储 int n = TInt ( ) << stream; //从流中读取一个整数赋给n double d = TDouble ( ) << stream; //从流中读取一个浮点数给d 很显然,以上类模板(TDataIO)还可以适应定长的构造类型(struct/class), 但构造类型中不能包含指针对象和虚函数,否则在读取操作之后, 相应对象的多态性和指针对象的存取将会导致意料不到的后果! 如果它已经在运行了,那可惨了! 赶紧选择(Run|Program Reset)命令吧。 难道这个类模板的功能如此差劲,被这么个小问题都搞得死去活来 ? 还好,天无绝人之路,对于构造类型,可以使用以上类模板对指针对象分别进行处理, 同样能save/load构造类型中的指针对象,同时还可消除虚函数对流操作的影响, 此外,还可对流类的版本控制带来直接的益处,请参见“流类的版本控制”。 |