﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Ling Xu 的 C++ 技术随笔</title><link>http://www.cppblog.com/xlshcn/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 06 Apr 2026 11:41:06 GMT</lastBuildDate><pubDate>Mon, 06 Apr 2026 11:41:06 GMT</pubDate><ttl>60</ttl><item><title>C++ 初始化函数的实现</title><link>http://www.cppblog.com/xlshcn/archive/2007/11/21/cppinitializer.html</link><dc:creator>Ling Xu</dc:creator><author>Ling Xu</author><pubDate>Wed, 21 Nov 2007 08:31:00 GMT</pubDate><guid>http://www.cppblog.com/xlshcn/archive/2007/11/21/cppinitializer.html</guid><wfw:comment>http://www.cppblog.com/xlshcn/comments/37088.html</wfw:comment><comments>http://www.cppblog.com/xlshcn/archive/2007/11/21/cppinitializer.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/xlshcn/comments/commentRss/37088.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xlshcn/services/trackbacks/37088.html</trackback:ping><description><![CDATA[<p style="FONT-FAMILY: Lucida Console">讲一点和实现细节相关的东西。在Visual C++中，所有在main之前执行的函数调用实际上都通过一个自动生成的函数来调用，比如下面这段代码：</p>
<p style="FONT-FAMILY: Lucida Console">int func()<br>{<br>&nbsp;return 1;<br>}</p>
<p style="FONT-FAMILY: Lucida Console">int data = func();</p>
<p style="FONT-FAMILY: Lucida Console">int main()<br>{<br>&nbsp;return 0;<br>}</p>
<p style="FONT-FAMILY: Lucida Console">实际上生成了三个函数：</p>
<p style="FONT-FAMILY: Lucida Console"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#63;&#102;&#117;&#110;&#99;&#64;&#64;&#89;&#65;&#72;&#88;&#90;">?func@@YAHXZ</a>，对应于 func<br>_main 对应于 main<br>_$E1 对应于 data=func() 这句赋值语句。它调用了 func，并且完成赋值这个操作。</p>
<p style="FONT-FAMILY: Lucida Console">窍门在于，VC将 _$E1这个函数的指针放到了段CRT$XCU中：</p>
<p style="FONT-FAMILY: Lucida Console">CRT$XCU SEGMENT<br>_$S2 DD FLAT:_$E1<br>; Function compile flags: /Odt /RTCsu /ZI<br>CRT$XCU ENDS</p>
<p style="FONT-FAMILY: Lucida Console">这个段的定义为：</p>
<p style="FONT-FAMILY: Lucida Console">CRT$XCU SEGMENT DWORD USE32 PUBLIC 'DATA'<br>CRT$XCU ENDS</p>
<p style="FONT-FAMILY: Lucida Console">参考 crt0dat.c 文件可以看到：</p>
<p style="FONT-FAMILY: Lucida Console">extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];<br>extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];&nbsp;&nbsp;&nbsp; /* C initializers */<br>extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];<br>extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];&nbsp;&nbsp;&nbsp; /* C++ initializers */<br>extern _CRTALLOC(".CRT$XPA") _PVFV __xp_a[];<br>extern _CRTALLOC(".CRT$XPZ") _PVFV __xp_z[];&nbsp;&nbsp;&nbsp; /* C pre-terminators */<br>extern _CRTALLOC(".CRT$XTA") _PVFV __xt_a[];<br>extern _CRTALLOC(".CRT$XTZ") _PVFV __xt_z[];&nbsp;&nbsp;&nbsp; /* C terminators */</p>
<p style="FONT-FAMILY: Lucida Console">这里实际上有一个很巧妙的地方在于，VC应用了x86上段是连续并且可重叠的概念，因此CRT$XCU是位于CRT$XCA到CRT$XCZ之间，具体说，段的顺序是：</p>
<p style="FONT-FAMILY: Lucida Console">CRT$XCA&nbsp;SEGMENT DWORD USE32 PUBLIC 'DATA'<br>CRT$XCA&nbsp;ENDS<br>CRT$XCU&nbsp;SEGMENT DWORD USE32 PUBLIC 'DATA'<br>CRT$XCU&nbsp;ENDS<br>CRT$XCL&nbsp;SEGMENT DWORD USE32 PUBLIC 'DATA'<br>CRT$XCL&nbsp;ENDS<br>CRT$XCC&nbsp;SEGMENT DWORD USE32 PUBLIC 'DATA'<br>CRT$XCC&nbsp;ENDS<br>CRT$XCZ&nbsp;SEGMENT DWORD USE32 PUBLIC 'DATA'<br>CRT$XCZ&nbsp;ENDS</p>
<p style="FONT-FAMILY: Lucida Console">由于CRT$XCA开始都是C++初始化函数，_PVFV实际上就是 void (*_PVFV)()，因此CRT的_initterm()函数就把这个段中的数据作为一个函数指针数组来访问，依次调用其中的函数，从而完成系统所有初始化操作。</p>
<p style="FONT-FAMILY: Lucida Console">最后，也是最关键的问题，就是实际上每个 CPP 文件编译好以后都有初始化函数，并且其指针位于 CRT$XC? 段中，随后连接程序 LINK 做了最后一个重要的任务，就是把所有具有相同名字的段合并成为一个单独的段（这也就是连接程序名字的由来之一），合并的做法就是简单地把每个段中的数据按顺序前后放到一个连续的空间就可以了。这样在最终运行的时候，程序看到的CRT$XC?段也就是一个连续的数组，而不是多个数组。</p>
<p style="FONT-FAMILY: Lucida Console">至于顺序问题，在这里就可以看到，是由连接程序最后做拼接时候确定的。连接程序拼接的顺序，基本上是它看到OBJ文件的顺序，也就是在连接程序命令行指定的顺序。因此，在程序中决不能依赖于这个顺序，因为在连接程序命令行中的文件顺序是不确定的。</p>
<p style="FONT-FAMILY: Lucida Console">以上是初始化程序的顺序，至于析构函数（或者在main函数之后的函数调用）则是通过用at_exit函数注册的顺序来确定，而注册往往是在初始化的时候进行，因此析构函数的调用顺序也是不确定的。</p>
<p style="FONT-FAMILY: Lucida Console">&nbsp;</p>
<p style="FONT-FAMILY: Lucida Console"><br>&nbsp;</p>
<img src ="http://www.cppblog.com/xlshcn/aggbug/37088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xlshcn/" target="_blank">Ling Xu</a> 2007-11-21 16:31 <a href="http://www.cppblog.com/xlshcn/archive/2007/11/21/cppinitializer.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ XML  序列化器</title><link>http://www.cppblog.com/xlshcn/archive/2007/11/21/cppxmlserializer.html</link><dc:creator>Ling Xu</dc:creator><author>Ling Xu</author><pubDate>Wed, 21 Nov 2007 08:06:00 GMT</pubDate><guid>http://www.cppblog.com/xlshcn/archive/2007/11/21/cppxmlserializer.html</guid><wfw:comment>http://www.cppblog.com/xlshcn/comments/37087.html</wfw:comment><comments>http://www.cppblog.com/xlshcn/archive/2007/11/21/cppxmlserializer.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/xlshcn/comments/commentRss/37087.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xlshcn/services/trackbacks/37087.html</trackback:ping><description><![CDATA[<p style="FONT-FAMILY: Courier">XML 序列化器</p>
<p style="FONT-FAMILY: Courier">最近试图编写一个C++的XML序列化器，目前实现了一些基本的功能。为了开发一个XML序列化器，首先要有XML读取器（Reader）和书写器（Writer）。我实现了两个简单的XML Reader和Writer：</p>
<p style="FONT-FAMILY: Courier"><br>&nbsp;</p>
<div style="FONT-FAMILY: Courier"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;SimpleXmlElement<br><img id=Codehighlighter1_31_544_Open_Image onclick="this.style.display='none'; Codehighlighter1_31_544_Open_Text.style.display='none'; Codehighlighter1_31_544_Closed_Image.style.display='inline'; Codehighlighter1_31_544_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_31_544_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_31_544_Closed_Text.style.display='none'; Codehighlighter1_31_544_Open_Image.style.display='inline'; Codehighlighter1_31_544_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;public:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum&nbsp;NodeType<br><img id=Codehighlighter1_75_175_Open_Image onclick="this.style.display='none'; Codehighlighter1_75_175_Open_Text.style.display='none'; Codehighlighter1_75_175_Closed_Image.style.display='inline'; Codehighlighter1_75_175_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_75_175_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_75_175_Closed_Text.style.display='none'; Codehighlighter1_75_175_Open_Image.style.display='inline'; Codehighlighter1_75_175_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNKNOWN,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ATTRIBUTE,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ELEMENT,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENDOFELEMENT<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;private:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;class&nbsp;SimpleXmlReader;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;public:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NodeType&nbsp;GetType()&nbsp;const;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;GetName()&nbsp;const;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;IsEmptyElement()&nbsp;const;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;protected:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Reset(NodeType&nbsp;type,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;name,&nbsp;bool&nbsp;isEmptyElement);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;private:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NodeType&nbsp;m_type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;m_name;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;m_isEmptyElement;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;};<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;SimpleXmlAttribute:&nbsp;public&nbsp;SimpleXmlElement<br><img id=Codehighlighter1_606_817_Open_Image onclick="this.style.display='none'; Codehighlighter1_606_817_Open_Text.style.display='none'; Codehighlighter1_606_817_Closed_Image.style.display='inline'; Codehighlighter1_606_817_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_606_817_Closed_Image onclick="this.style.display='none'; Codehighlighter1_606_817_Closed_Text.style.display='none'; Codehighlighter1_606_817_Open_Image.style.display='inline'; Codehighlighter1_606_817_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;class&nbsp;SimpleXmlReader;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;public:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;GetValue()&nbsp;const;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;protected:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Reset(const&nbsp;String&nbsp;&amp;&nbsp;name,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;val);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;private:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;m_val;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;};<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;SimpleXmlReader<br><img id=Codehighlighter1_851_1449_Open_Image onclick="this.style.display='none'; Codehighlighter1_851_1449_Open_Text.style.display='none'; Codehighlighter1_851_1449_Closed_Image.style.display='inline'; Codehighlighter1_851_1449_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_851_1449_Closed_Image onclick="this.style.display='none'; Codehighlighter1_851_1449_Closed_Text.style.display='none'; Codehighlighter1_851_1449_Open_Image.style.display='inline'; Codehighlighter1_851_1449_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;public:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SimpleXmlReader();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~SimpleXmlReader();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Open(IStream&nbsp;*&nbsp;stream,&nbsp;ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Open(const&nbsp;void&nbsp;*&nbsp;buffer,&nbsp;SIZE_TYPE&nbsp;length,&nbsp;ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Open(const&nbsp;void&nbsp;*&nbsp;buffer,&nbsp;int&nbsp;offset,&nbsp;SIZE_TYPE&nbsp;length,&nbsp;ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;bool&nbsp;IsEndOfStream()&nbsp;const;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;const&nbsp;SimpleXmlElement&nbsp;*&nbsp;GetNextElement();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;const&nbsp;SimpleXmlAttribute&nbsp;*&nbsp;GetNextAttribute();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;const&nbsp;String&nbsp;GetElementInnerText();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;};<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;//-------------------------------------------------------------------------------------------<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;SimpleXmlWriter<br><img id=Codehighlighter1_1583_2134_Open_Image onclick="this.style.display='none'; Codehighlighter1_1583_2134_Open_Text.style.display='none'; Codehighlighter1_1583_2134_Closed_Image.style.display='inline'; Codehighlighter1_1583_2134_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_1583_2134_Closed_Image onclick="this.style.display='none'; Codehighlighter1_1583_2134_Closed_Text.style.display='none'; Codehighlighter1_1583_2134_Open_Image.style.display='inline'; Codehighlighter1_1583_2134_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;public:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SimpleXmlWriter();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~SimpleXmlWriter();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Open(ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Open(IStream&nbsp;*&nbsp;stream,&nbsp;ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;EnterElement(const&nbsp;String&nbsp;&amp;&nbsp;element);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;AddAttribute(const&nbsp;String&nbsp;&amp;&nbsp;attribute,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;value);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SetElementInnerText(const&nbsp;String&nbsp;&amp;&nbsp;text);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;LeaveElement();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;const&nbsp;void&nbsp;*&nbsp;GetBuffer();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;SIZE_TYPE&nbsp;GetLength();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;};<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></div>
<p style="FONT-FAMILY: Courier"><br>在这两个类中，IStream是保存数据的流接口，ICharsetEncoding是用于字符集转换的编码接口。</p>
<p style="FONT-FAMILY: Courier">使用这两个类就可以进行XML序列化了。</p>
<p style="FONT-FAMILY: Courier">&nbsp;</p>
<div style="FONT-FAMILY: Courier">&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;XmlSerializer;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;IXmlSerializable<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Serialize(XmlSerializer&nbsp;*&nbsp;serializer,&nbsp;bool&nbsp;serialize)&nbsp;=&nbsp;0;<br>&nbsp;&nbsp;&nbsp;&nbsp;};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;XmlTree;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;XmlSerializer<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XmlSerializer();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~XmlSerializer();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;OpenSerializer(IStream&nbsp;*&nbsp;stream,&nbsp;ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;OpenDeserializer(IStream&nbsp;*&nbsp;stream,&nbsp;ICharsetEncoding&nbsp;*&nbsp;encoding&nbsp;=&nbsp;NULL);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Close();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;bool&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;int&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;IXmlSerializable&nbsp;&amp;&nbsp;var);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeAttribute(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;attributeName,&nbsp;bool&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeAttribute(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;attributeName,&nbsp;int&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;SerializeAttribute(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;attributeName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;bool&nbsp;&amp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;int&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;String&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeElement(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;IXmlSerializable&nbsp;&amp;&nbsp;var);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeAttribute(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;attributeName,&nbsp;bool&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeAttribute(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;attributeName,&nbsp;int&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;DeserializeAttribute(const&nbsp;String&nbsp;&amp;&nbsp;className,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;elementName,&nbsp;const&nbsp;String&nbsp;&amp;&nbsp;attributeName,&nbsp;String&nbsp;&amp;&nbsp;var);<br>&nbsp;&nbsp;&nbsp;};<br><br>#define&nbsp;BEGIN_XML_SERIALIZER_BASE(className,&nbsp;baseClassName)&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Serialize(XmlSerializer&nbsp;*&nbsp;serializer,&nbsp;bool&nbsp;serialize)&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;String&nbsp;__className&nbsp;=&nbsp;TEXT(#className);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(IsTypeDerivedFrom&lt;baseClassName,&nbsp;IXmlSerializable&gt;::Yes)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseClassName::Serialize(serializer,&nbsp;serialize);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>#define&nbsp;BEGIN_XML_SERIALIZER(className)&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;Serialize(XmlSerializer&nbsp;*&nbsp;serializer,&nbsp;bool&nbsp;serialize)&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;String&nbsp;__className&nbsp;=&nbsp;TEXT(#className);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>#define&nbsp;END_XML_SERIALIZER()&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>#define&nbsp;XML_ELEMENT(var)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(serialize)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serializer-&gt;SerializeElement(__className,&nbsp;TEXT(#var),&nbsp;var);&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serializer-&gt;DeserializeElement(__className,&nbsp;TEXT(#var),&nbsp;var);&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>#define&nbsp;XML_ATTRIBUTE(element,&nbsp;var)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(serialize)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serializer-&gt;SerializeAttribute(__className,&nbsp;TEXT(#element),&nbsp;TEXT(#var),&nbsp;var);&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serializer-&gt;DeserializeAttribute(__className,&nbsp;TEXT(#element),&nbsp;TEXT(#var),&nbsp;var);&nbsp;\<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></div>
<p style="FONT-FAMILY: Courier">&nbsp;</p>
<p style="FONT-FAMILY: Courier">有一个模板类 IsTypeDerivedFrom&lt;T, U&gt;用于判断类型T是否从类型U派生。如果是，那么Yes=1，否则Yes=0。</p>
<p style="FONT-FAMILY: Courier">为了序列化一个类，首先从 IXmlSerializable 接口派生（实际上如果这个类不作为其它序列化类的基类的化，也可以不用从该接口派生），然后使用 BEGIN_XML_SERIALIZER （对于单独的类）或者 BEGIN_XML_SERIALIZER_BASE（对于需要序列化基类的情况）开始定义序列化器。例如：</p>
<p style="FONT-FAMILY: Courier">&nbsp;</p>
<div style="FONT-FAMILY: Courier">class&nbsp;ClassA:&nbsp;public&nbsp;IXmlSerializable<br>{<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;BEGIN_XML_SERIALIZER(ClassA)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_data)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ATTRIBUTE(m_data,&nbsp;m_value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_bool)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_s)<br>&nbsp;&nbsp;&nbsp;&nbsp;END_XML_SERIALIZER();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ClassA()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;m_data(0),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_value(1),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_bool(false),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_s(TEXT("Hello"))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Reset()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_data&nbsp;=&nbsp;-1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_value&nbsp;=&nbsp;0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_bool&nbsp;=&nbsp;true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_s&nbsp;=&nbsp;TEXT("");<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_data;<br>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_value;<br>&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;m_bool;<br>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;m_s;<br>};<br><br>class&nbsp;ClassC:&nbsp;public&nbsp;ClassA<br>{<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;BEGIN_XML_SERIALIZER_BASE(ClassC,&nbsp;ClassA)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_data)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ATTRIBUTE(m_data,&nbsp;m_value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_bool)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_s)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XML_ELEMENT(m_a)<br>&nbsp;&nbsp;&nbsp;&nbsp;END_XML_SERIALIZER();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ClassC()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;m_data(0),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_value(1),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_bool(false),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_s(TEXT("Hello"))<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Reset()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_data&nbsp;=&nbsp;-1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_value&nbsp;=&nbsp;0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_bool&nbsp;=&nbsp;true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_s&nbsp;=&nbsp;TEXT("");<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_data;<br>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_value;<br>&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;m_bool;<br>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;m_s;<br>&nbsp;&nbsp;&nbsp;&nbsp;ClassA&nbsp;m_a;<br>};<br></div>
<p style="FONT-FAMILY: Courier">&nbsp;</p>
<p style="FONT-FAMILY: Courier">执行下面的代码：</p>
<p style="FONT-FAMILY: Courier">&nbsp;</p>
<div style="FONT-FAMILY: Courier">XmlSerializer&nbsp;serializer;<br>MemoryStream&nbsp;ms;<br><br>ms.Open();<br>serializer-&gt;OpenSerializer(&amp;ms);<br><br>ClassC&nbsp;c;<br><br>c.Serialize(&amp;serializer,&nbsp;true);<br><br>serializer.Close();<br><br>const&nbsp;char&nbsp;*&nbsp;buf&nbsp;=&nbsp;static_cast&lt;const&nbsp;char&nbsp;*&gt;(ms.GetBuffer());<br></div>
<p style="FONT-FAMILY: Courier">&nbsp;</p>
<p style="FONT-FAMILY: Courier">这样 buf 中就包含了序列化以后的XML文本，如下：<br></p>
<div style="FONT-FAMILY: Courier">&lt;SerializeData&gt;<br>&nbsp;&lt;ClassA&gt;<br>&nbsp;&nbsp;&lt;m_bool&gt;false&lt;/m_bool&gt;<br>&nbsp;&nbsp;&lt;m_data&nbsp;m_value="1"&gt;0&lt;/m_data&gt;<br>&nbsp;&nbsp;&lt;m_s&gt;Hello&lt;/m_s&gt;<br>&nbsp;&lt;/ClassA&gt;<br>&nbsp;&lt;ClassC&gt;<br>&nbsp;&nbsp;&lt;m_a&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ClassA&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;m_bool&gt;false&lt;/m_bool&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;m_data&nbsp;m_value="1"&gt;0&lt;/m_data&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;m_s&gt;Hello&lt;/m_s&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/ClassA&gt;<br>&nbsp;&nbsp;&lt;/m_a&gt;<br>&nbsp;&nbsp;&lt;m_bool&gt;false&lt;/m_bool&gt;<br>&nbsp;&nbsp;&lt;m_data&nbsp;m_value="1"&gt;0&lt;/m_data&gt;<br>&nbsp;&nbsp;&lt;m_s&gt;Hello&lt;/m_s&gt;<br>&nbsp;&lt;/ClassC&gt;<br>&lt;/SerializeData&gt;</div>
<p style="FONT-FAMILY: Courier"><br>实际的序列化后的文本是不包含缩进的，上面这样只是为了便于浏览。</p>
<p style="FONT-FAMILY: Courier">使用 c.Serialize(&amp;serializer, false) 可以执行反序列化，即从 XML 文本生成对应的对象。</p>
<p style="FONT-FAMILY: Courier">【限制】</p>
<p style="FONT-FAMILY: Courier">目前尚没有实现对数组的序列化，对于指针，考虑不做序列化，原因在于涉及到内存的分配以及动态多态等问题不是很好解决。<br></p>
<img src ="http://www.cppblog.com/xlshcn/aggbug/37087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xlshcn/" target="_blank">Ling Xu</a> 2007-11-21 16:06 <a href="http://www.cppblog.com/xlshcn/archive/2007/11/21/cppxmlserializer.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>