﻿<?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++博客-Michael's Space-文章分类-COM/ATL</title><link>http://www.cppblog.com/MichaelLiu/category/1442.html</link><description>Technology changes the world, serves the people.</description><language>zh-cn</language><lastBuildDate>Sun, 25 May 2008 02:07:49 GMT</lastBuildDate><pubDate>Sun, 25 May 2008 02:07:49 GMT</pubDate><ttl>60</ttl><item><title>从C++到COM</title><link>http://www.cppblog.com/MichaelLiu/articles/22142.html</link><dc:creator>奔跑的阿甘</dc:creator><author>奔跑的阿甘</author><pubDate>Tue, 17 Apr 2007 09:24:00 GMT</pubDate><guid>http://www.cppblog.com/MichaelLiu/articles/22142.html</guid><wfw:comment>http://www.cppblog.com/MichaelLiu/comments/22142.html</wfw:comment><comments>http://www.cppblog.com/MichaelLiu/articles/22142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MichaelLiu/comments/commentRss/22142.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MichaelLiu/services/trackbacks/22142.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 从C++到COMMichael&nbsp; Tuesday, April 17, 2007这是George Shepherd, Brad King所著《Inside ATL》的对ATL的核心－COM的前因后果的阐述，非常适合C++程序员入门COM的教材！文章较长，但耐心读完后如醍醐灌顶，对COM的本质将会有非常清晰的认识。&nbsp;&nbsp;The Atoms of COMCOM ...&nbsp;&nbsp;<a href='http://www.cppblog.com/MichaelLiu/articles/22142.html'>阅读全文</a><img src ="http://www.cppblog.com/MichaelLiu/aggbug/22142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MichaelLiu/" target="_blank">奔跑的阿甘</a> 2007-04-17 17:24 <a href="http://www.cppblog.com/MichaelLiu/articles/22142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COM数据类型</title><link>http://www.cppblog.com/MichaelLiu/articles/13385.html</link><dc:creator>奔跑的阿甘</dc:creator><author>奔跑的阿甘</author><pubDate>Thu, 05 Oct 2006 10:26:00 GMT</pubDate><guid>http://www.cppblog.com/MichaelLiu/articles/13385.html</guid><wfw:comment>http://www.cppblog.com/MichaelLiu/comments/13385.html</wfw:comment><comments>http://www.cppblog.com/MichaelLiu/articles/13385.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MichaelLiu/comments/commentRss/13385.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MichaelLiu/services/trackbacks/13385.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: COM数据类型Michael 2006年10月5日本文根据DON BOX大师《Essential COM》第2.11章节文章，对COM中IDL的数据类型的用法进行了总结。IDL数据类型的设计思想是要保证类型的“语言独立”和“平台独立”，例如它需要能被C++/VB/Java等语言和Windows（各版本）和Solaris等平台识别和支持。1。基本类型全是小写的字符表示。包括：boolean, byt...&nbsp;&nbsp;<a href='http://www.cppblog.com/MichaelLiu/articles/13385.html'>阅读全文</a><img src ="http://www.cppblog.com/MichaelLiu/aggbug/13385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MichaelLiu/" target="_blank">奔跑的阿甘</a> 2006-10-05 18:26 <a href="http://www.cppblog.com/MichaelLiu/articles/13385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COM的由来</title><link>http://www.cppblog.com/MichaelLiu/articles/9388.html</link><dc:creator>奔跑的阿甘</dc:creator><author>奔跑的阿甘</author><pubDate>Tue, 04 Jul 2006 09:59:00 GMT</pubDate><guid>http://www.cppblog.com/MichaelLiu/articles/9388.html</guid><wfw:comment>http://www.cppblog.com/MichaelLiu/comments/9388.html</wfw:comment><comments>http://www.cppblog.com/MichaelLiu/articles/9388.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MichaelLiu/comments/commentRss/9388.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MichaelLiu/services/trackbacks/9388.html</trackback:ping><description><![CDATA[
		<font face="Arial" size="2">
				<b>
						<font size="3">COM的由来</font>
				</b>
				<br />Michael 2006年07月04日<br /><br />最近，公司的产品在支持SNA网络时出现了一个怪异的问题，终端和主机连接总是无法建立，经过追查源码发现应用客户端在调用SNA网络服务库的接口时莫名其妙的改变了网络服务对象的数据成员，实际上，该数据成员只有在对象构造函数中被初始化过一次，其他地方没有任何写操作。<br />根据应用客户端对多网络协议的支持代码，我做了以下测试，Client应用调用一个Operate接口，由两个不同的服务端实现：<br /><br />Client包含IOperator接口文件，调用operate方法：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><font><font face="Arial" size="2"><span style="color: rgb(0, 128, 128);">1</span> <span style="color: rgb(0, 0, 255);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EXPORIMP IOperator {<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">    IOperator();<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">IOperator();<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">    <br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2);<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">    <br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a;<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b;<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">};</span></font></font><span style="color: rgb(0, 0, 0);"></span></div><br />operate的第一个实现：server1.dll<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> </span><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"></span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 128);">1</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EXPORIMP IOperator {<br /></span><span style="color: rgb(0, 128, 128);">2</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);">3</span> <span style="color: rgb(0, 0, 0);">      IOperator();<br /></span><span style="color: rgb(0, 128, 128);">4</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">IOperator();<br /></span><span style="color: rgb(0, 128, 128);">5</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);">6</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2);<br /></span><span style="color: rgb(0, 128, 128);">7</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);">8</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);">9</span> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a;<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b;<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"> };</span></div><span style="color: rgb(0, 0, 0);"></span></div><br />operate的第二个实现：增强的server1.dll<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span><span style="color: rgb(0, 0, 255);"></span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EXPORIMP IOperator {<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">    IOperator(); // Initialize szName, a, b<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">IOperator();<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">    <br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2); //access szName<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">    <br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> szName[</span><span style="color: rgb(0, 0, 0);">256</span><span style="color: rgb(0, 0, 0);">];<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a;<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b;<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">};</span></div><br />client通过server1.lib来实现接口调用，server1的发布者在发布dll后发现server1中存在某个BUG，或者为了改进operate的效率，因而引入了szName成员并更新了operate接口实现，然后重新发布了增强版的server1 DLL。客户拿到新版本后很高兴，但是，当他兴致勃勃地替换掉老的DLL时，发现自己的客户端再也跑不起来了，令人厌烦的异常！<br />我们发现两种实现的唯一区别是私有数据成员的组成，但是DLL的PUBLIC接口没有变化为什么会出现异常呢？<br />原来，客户端在第一次编译时引入老的server1.lib，并没有准备为新的dll分配256个char变量，但是客户端调用的新的dll接口时却对不属于自己的内存块做了操作，其实，客户端在创建IOperator对象时就出错了！<br />我们称以上的接口定义为“老”的接口定义方式，这种方式下，如果改变了数据成员而且公用接口对数据成员又做了操作，那么在不重新编译客户程序的情况下，客户程序将毫无疑问的出现异常甚至崩溃。<br /><br />封装－C++的三大特性之一，在这里迷惑了我们的视眼。因为利用PRIVATE和PUBLIC关键字定义的封装是“<b>语法</b>”上的封装，也就是说，在同一工程内是不能够直接访问PRIVATE的成员的，否则编译器会报告语法错误，实际上，编译器在编译重用库的时候还是需要访问重用类的所有成员（包括PRIVATE），以便在客户中构造类对象。这样，“接口”和“实现”实际上是一个东西。<br />“接口”和“实现”的真正分离，要求C++的“封装”是种“二进制层次”的封装。也就是说，不管重用类的实现如何改变，它提供的接口对于客户来说都是静止的。因此，我们把接口类和实现类分离的时候，要让接口类的二进制布局不会随着实现类的变化而变化。<br />下述对接口类和实现类的分离是成功的，因为不论实现类如何改进，接口IOperatorItf的内存布局从未改变。但是，一个残酷的问题是，IOperatorItf类必须声明IOperator的所有拥有的接口，对于一个稍微大型的类来说，这是个烦琐的过程，而且，嵌套调用的开销也不可忽略。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 255);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EXPORIMP IOperatorItf {    //接口类<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> IOperator;<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">IOperator</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> m_pThis;<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">      IOperator();<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">IOperator();<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2);<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);"> };<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);"></span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> EXPORIMP IOperator {   //实现类<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">      IOperator();<br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">IOperator();<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2);<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a;<br /></span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b;<br /></span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);"> };</span></div><br />这里还有个非常关键的问题，上述改进并没有解决编译器/链接器的标识符名字改编问题，这造成严重的编译器/链接器依赖。<br />编译器之间不可避免的在编译细节上存在多种差异，然而，有一条特性却是所有的编译器都满足的：“<b>某个给定平台上的所有C++编译器都实现了同样的虚函数调用机制</b>”，即对于每个编译器，类的对象在内存中如何表示，以及在运行时虚函数如何被动态调用，都是一样的。这个特性非常漂亮的解决上述问题。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">接口类</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> IOperatorItf {<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">      vritual </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2)＝</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"> };<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">extern</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> IOperatorItf</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> CreateOperatorInstance();<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">实现类</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> IOperator : </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> IOperatorItf {<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">      IOperator() {a=b=1};<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">IOperator();<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> operate(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var1, </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> var2) {return (a+b)};<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">      <br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a;<br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b;<br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);"> };<br /></span><font><font face="Arial" size="2"><span style="color: rgb(0, 128, 128);">20 </span></font></font><font><font face="Arial" size="2"><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">extern</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> IOperatorItf</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> CreateOperatorInstance() { return (new IOperator)};</span></font></font><font><font face="Arial" size="2"><span style="color: rgb(0, 128, 128);"></span></font></font></div><br />这里，接口类和实现类在定义上是独立的，但是因为继承，实现类的内存布局是接口类布局的二进制超集，这种“二进制层次”的继承解决了我们前面几种方案的所有问题。<br /><br />“接口”和“实现”的分离是重用组件的核心，当我们学会用虚函数表来表达我们的接口时，COM已经在向我们招手了。<br /><br />[完]<br /></font>
<img src ="http://www.cppblog.com/MichaelLiu/aggbug/9388.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MichaelLiu/" target="_blank">奔跑的阿甘</a> 2006-07-04 17:59 <a href="http://www.cppblog.com/MichaelLiu/articles/9388.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>