Windows MobileVisual C++ 7.1Visual C++ 8.0Visual C++ 7.0Visual Studio .NET 2003Windows 2000Visual C++ 6.0Windows XP中级开发Visual StudioWindowsC++.NET
派生自流的Encoder类






3.05/5 (7投票s)
2004年9月2日
2分钟阅读

37611

674
如何实现一个从 Xstream 类派生的类,以及如何从中进行序列化。
引言
通常,您希望向流类(istream
,ostream
或 iostream
)添加特殊功能。 实现此目的的一种方法是创建一个专门的 streambuf
类并重载流基类方法。
一个 Xstream
类构造函数有一个 streambuf
参数,该参数附加到流。 例如,要写入文件,您可以这样做
filebuf fb; fb.open ("test.txt",ios::out); ostream os(&fb); //...
但是,如果您的目标不是写入文件,而是写入通用内存缓冲区,则可以这样构造您的 ostream
派生类
class MyStreamBuf : public streambuf { // ... you can overload streambuf methods here }; class MyOutputStream : public ostream { public: MyOutputStream() : ostream(&stBuf) {} // ... you can overload ostream methods here private: MyStreamBuf stBuf; };
istream
和 iostream
类也一样。 重载 Xstream
方法允许您创建一个专门的流类。
如果要将基本类型或其他对象序列化为 MyOutputStream
,则必须创建一个返回 MyOutputStream
引用对象的 方法,以便您可以编写如下内容
MyOutputStream mos;
mos << "hello";
现在,我们来看一个示例,将此技术应用于 Encoder
类,其中编码操作可以这样执行
Encoder obj; obj << "Hello"; //encode the "Hello" string e put it into an Encoder stream and the decode operation can be performed so string str; obj >> str; //decoding in str
使用代码
在这里,我们将看到一个示例,该示例允许通过 ostream
的派生类的运算符 <<
和 >>
来操作字符串。 此外,我们创建一个专门的 streamuf
类,用于编码和解码字符串缓冲区。
在此示例代码中,正如我们之前解释的那样,字符串可以这样编码和解码
Encoder y; y << "Hello" //encode a string into a stream y >> str; //decode stream into a string
Encode
方法仅包含字符串中 char
的 ASCII 转换,而 Decode
则反转此操作。
#include <string> #include <fstream> #include <iostream> using namespace std; class BufferEncoder: public streambuf { private: string buffer; //encoded string int numCar; //chars number of encoded string public: BufferEncoder() : streambuf(), numCar(0) {} ~BufferEncoder() {} //encode a string and put it into BufferEncoder buffer void Encode(const string& s){ char tmp[10]; for (unsigned int i=0; i< s.length(); ++i){ itoa(s[i],tmp,10); buffer+= (string)tmp + (string)" "; //encode in an ASCII value numCar +=strlen(tmp)+1; } } //decode BufferEncoder buffer and return it into s void Decode(string& s){ string decodeStr; for (int i=0; i< numCar;++i){ string tokenStr; while ((buffer.at(i) != ' ')&& (buffer.at(i)!='\n') && (i< numCar)){ tokenStr += buffer.at(i); i++; } int v = atoi(tokenStr.c_str()); decodeStr += (char) v; //decoded char } s = decodeStr; } //add and end of line into buffer void EndOfLine() { buffer += '\n'; numCar ++; } //return buffer pointer char* GetBuffer() {return ((char*) buffer.c_str());} }; class Encoder : public ostream { private: BufferEncoder myStrBuf; public: //constructors Encoder(filebuf* fb) : ostream(fb),ios(0) {} Encoder() : ostream(&myStrBuf),ios(0) {} //endl manipulator serialization _Myt& operator<<(_Myt&(__cdecl *_Pfn )(_Myt&) ){ // call basic_ostream manipulator //... no others manipulators than endl myStrBuf.EndOfLine(); return ((*_Pfn)(*this)); } //from Encoder to ostream serialization friend ostream& operator<<(ostream & s, Encoder& c) { s << c.myStrBuf.GetBuffer(); return s; } //from const char* to Encoder serialization Encoder& operator<<(const char * s) { myStrBuf.Encode(s); return *this; } //from Encoder to string serialization Encoder& operator>>(string& s) { myStrBuf.Decode(s); return *this; } }; int main () { Encoder y; //encoding y <<"Hello World!"; cout <<"ENCODED: "<< y << endl; //decoding string s ; y >> s; cout << "DECODED: " << s << endl; return 0; }
关注点
此代码可以帮助您学习如何将对象(基本类型或用户定义)序列化到或从对象流,例如预定义对象 cin
和 cout
。 实际上,就像一个 istream
对象 cin
和 ostream
对象 cout
一样,在 C++ 中,您可以从这些类定义派生和用户定义的对象,并创建到或从这些对象的方法。
历史
- v 1.1 修复了一些代码样式技巧
- v 1.0