﻿<?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++博客-qiezi的学习园地-随笔分类-C＋＋</title><link>http://www.cppblog.com/cpunion/category/49.html</link><description>AS/C/C++/D/Java/JS/Python/Ruby</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 02:40:29 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 02:40:29 GMT</pubDate><ttl>60</ttl><item><title>泛型矩阵类</title><link>http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 13 Apr 2006 05:52:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/5464.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/5464.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/5464.html</trackback:ping><description><![CDATA[<p>
		</p>
		<p>矩阵就不用再解释了，写成泛型主要是为了几个方便：<br />1、方便在栈上分配空间。由于维度在编译期已知，所以可以做到在栈上分配空间。当然如果这个对象是new出来的，自然是在堆上分配，这里说的是在栈上分配这个对象时，矩阵元素所占用的空间也在栈上分配。<br />2、方便在编译期检查非法的矩阵运算。C++模板的强大推导能力可以在编译期推导出结果矩阵的维度。<br />3、泛型类在方法内联上具有优势。<br /><br />这个矩阵类为了能够直接从数组赋值，使用了一个ArrayPorxy类（可参考《Imperfect C++》）。<br /><br />代码如下：<br /><br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">template </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> T, </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> D1, </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> D2</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> ArrayProxy<br />{<br />    T</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> data;<br /></span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000">:<br />    ArrayProxy(T (</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">value)[D1][D2])<br />        : data(</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">value[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">][</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">])<br />    {<br />    }<br /><br />    ArrayProxy(T (</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">value)[D1</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">D2])<br />        : data(value)<br />    {<br />    }<br /><br />    T</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> getData() </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000">
						<br />    {<br />        </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> data;<br />    }<br />};</span>
		</div>
		<br />这个只是简单的实现。<br /><br />因为我基本上不使用这个矩阵类，所以只完成几个简单功能：<br />1、从数组赋值：<br />int a[][3] = {{1,2,3}, {4,5,6}};<br />Matrix&lt;int, 2, 3&gt; m1(a);<br />或<br />int a[] = {1,2,3, 4,5,6};<br />Matrix&lt;int, 2, 3&gt; m1(a);<br />Matrix&lt;int, 3, 2&gt; m2(a);<br />Matrix&lt;int, 6, 1&gt; m3(a);<br />Matrix&lt;int, 1, 6&gt; m4(a);<br /><br />2、矩阵乘法：<br />Matrix&lt;int, 2, 3&gt; m1;<br />Matrix&lt;int, 2, 4&gt; m2;<br />// m1 * m2  &lt;== 编译错误，维度不匹配<br />Matrix&lt;int, 3, 5&gt; m3;<br />Matrix&lt;int, 2, 5&gt; m4 = m1 * m3; // &lt;== 合法<br />// m3 * m1; // &lt;== 编译错误，维度不匹配<br /><br />源码如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Matrix<br />{<br />    T matrix[R][C];<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Big three<img src="http://www.cppblog.com/images/dot.gif" /></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    Matrix(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br />    {<br />        memset(matrix, </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />    }<br /><br />    Matrix(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs)<br />    {<br />        memcpy(matrix, rhs.matrix, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />    }<br /><br />    Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs)<br />    {<br />        memcpy(matrix, rhs.matrix, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br />    }<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br />    Matrix(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ArrayProxy</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> arr)<br />    {<br />        memcpy(matrix, arr.getData(), </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />    }<br /><br />    </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">Matrix(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br />    {<br />    }<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br />    T </span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> r, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c) </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br />    {<br />        assert(c </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> C </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> R </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> matrix[r][c];<br />    }<br /><br />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> r, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c, T v)<br />    {<br />        assert(c </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> C </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> R </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />        matrix[r][c] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> getCols () </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> C;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> getRows () </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> R;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs) <span style="COLOR: #0000ff">const</span><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> memcmp(matrix, rhs.matrix, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix)) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs) <span style="COLOR: #0000ff">const</span><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> rhs);<br />    }<br />};<br /><br />template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> C, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> C1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> lhs, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,C,C1</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> rhs)<br />{<br />    Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> result;<br />    </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> r</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; r</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">R; </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">r)<br />    {<br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; c</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">C1; </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">c)<br />        {<br />            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> value </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">C; </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br />            {<br />                value </span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000"> lhs.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(r,i) </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> rhs.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i,c);<br />            }<br />            result.</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">(r,c,value);<br />        }<br />    }<br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result;<br />}</span></div><br />测试代码：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main()<br />{<br />    {<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 测试初始化</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m1;<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m2(m1);<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m3 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1;<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m4;<br />        m4 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1;<br /><br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            {<br />                assert (m1.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />                assert (m2.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />                assert (m3.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />                assert (m4.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />            }<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> a[] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m5(a);<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> b[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> { {</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">},<br />                        {</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">},<br />                        {</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">}};<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m6(b);<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m7(m5);<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m8 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m5;<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m9;<br />        m9 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m5;<br /><br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            {<br />                assert (m5.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m6.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m7.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m8.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m9.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />            }<br /><br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 维数不匹配，编译错误<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Matrix&lt;int, 4, 5&gt; m10 = m9;</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c[][</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">}};<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 数组大小不匹配，编译错误<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Matrix&lt;int, 3, 4&gt; m10(c);</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> d[] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">};<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 数组大小不匹配，编译错误<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Matrix&lt;int, 3, 4&gt; m11(d);<br /><br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 乘法维数不合适，无法相乘<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">m1 * m2;</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m12;<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 匹配，可以相乘</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m13 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1 </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m12;<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m14;<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 无法相乘<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Matrix&lt;int, 3, 3&gt; m15 = m1 * m14;<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 可以相乘</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m15 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m14 </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m1;<br />    }<br /><br />    {<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查点乘</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> a[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">}};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m1(a);<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> b[</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">}};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m2(b);<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">135</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">150</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">165</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">310</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">350</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">390</span><span style="COLOR: #000000">}};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m3(c);<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m4 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1 </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m2;<br />        assert(m4 </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> m3);<br /><br />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m4.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />}</span></div><br />补充：<br />1、加法、减法只需要2个矩阵维度相同即可。 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> lhs, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> rhs)<br />{<br />   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" /></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">}</span></div><br />2、由于1x1的矩阵可以看成一个标量，矩阵与标量运算结果维数与原矩阵相同，可以重载来实现。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> lhs, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix&lt;T,1,1&gt;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs)<br />{<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" /></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">}</span></div><br />3、由于类型泛化，可能某些合理的运算无法进行，比如float型矩阵，与一个int型标量运算等。这些最好是借助类型萃取等手段，推导出运算以后的类型。（c++0x中包含自动获取运算结果类型的关键字typeof，等几年就可以用了:)。GCC编译器中已有实现，不过似乎有BUG）。<br /><br />4、其它。泛型实现可能会有一些考虑不周的地方，强类型有强类型的好处，不过必须要有完整的泛型算法支撑，否则难以使用。也可以把泛型矩阵类从一个普通矩阵类派生，这样更容易写出通用算法，不过在实现上可能要借助于运行期多态，对于矩阵类来说并不合适。<br /><br />5、其它。。前面说C＋＋的模板相当强大，D语言模板到目前为止似乎已经完全实现了C＋＋模板的功能，还增加了一些比如字符串值参模板等特性，比C＋＋模板功能更多。在代码编写上，由于可以编写静态判断语句（编译期）以及静态断言，编写模板比C＋＋更容易。有时间可以试试用它写个矩阵类，纯粹是兴趣，这些东西真的很难用到，现成的库也挺多。<br /><br />6、其它。。。c++0x要提供“template typedef”，也就是可以这样定义：<br />template &lt;int R, int C&gt; typedef Matrix&lt;int, R, C&gt; MatrixInt;  // 定义类型，维度不定<br />template &lt;class T&gt; typedef Matrix&lt;T, 4, 4&gt; Matrix4x4; // 定义维度，类型不定<br />由此可以出定义行向量、列向量、标量等，当然实际使用起来可能没那么舒服了。<img src ="http://www.cppblog.com/cpunion/aggbug/5464.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-04-13 13:52 <a href="http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C＋＋/D/Python性能比较续</title><link>http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 03 Apr 2006 03:00:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4932.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4932.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4932.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 周末抽空做了点小测试，根据http://blog.vckbase.com/jzhang/archive/2006/03/28/18807.html中m网友修改的算法，python版本中读取所有行以后就做一个排序，再去除重复项。这个算法在我的机器上执行时间是1735ms左右，属于python版本中最快的一个。D版本暂还没想到有更优化的做法，D在处理以char[]作key的关联数组时，判断方法是先判断...&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/4932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-04-03 11:00 <a href="http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ABI Specifications 相关链接</title><link>http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 23 Mar 2006 08:08:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4493.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4493.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4493.html</trackback:ping><description><![CDATA[Itanium C++ ABI ($Revision: 1.86 $)<br />http://www.codesourcery.com/cxx-abi/abi.html<br /><br />C++ ABI Summary<br />http://www.codesourcery.com/cxx-abi/<br /><br />C++ ABI for IA-64: Code and Implementation Examples<br />http://www.codesourcery.com/cxx-abi/abi-examples.html<br /><br />C++ Vtable Example<br />http://www.codesourcery.com/cxx-abi/cxx-vtable-ex.html<br /><br /><br /><br />
Intel® Itanium® Processor-specific Application Binary Interface (ABI)<br />
http://developer.intel.com/design/itanium/downloads/245370.htm<br /><img src ="http://www.cppblog.com/cpunion/aggbug/4493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-23 16:08 <a href="http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sizeof，数组类型</title><link>http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 22 Mar 2006 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4455.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4455.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4455.html</trackback:ping><description><![CDATA[sizeof('a') 在C++里面是1，C里面是4。<br /><br />C里面字符常量、enum作整数常量对待，所以是sizeof('a')大小是4。<br /><br />C99标准6.6.6有说明。<br /><br />int a = 'a'; sizeof(a)大小是1。<br /><br />另：sizeof(x)用于对类型取大小，对表达式取大小应使用sizeof x;虽然编译器没给你报错。<br /><br /><br /><br />"aaa"的类型是char[4]，"aa"的类型是char[3]，这是数组类型，数组类型作为值传递时退化为指针类型，与函数类型相似(注)。<br /><br />注：void(int)是函数类型，void(*)(int)是函数指针类型，把函数作为值传递时，退化为函数指针类型。<br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/cpunion/aggbug/4455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-22 13:04 <a href="http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［C++之AOP］Aspect C++生成远程调用代码可能性探讨</title><link>http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 19 Dec 2005 14:50:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1888.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1888.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1888.html</trackback:ping><description><![CDATA[C++ 0x keynote（以下简称0x）中描述了这样一个看起来不错的东西：<BR><BR>1、本地调用代码： <PRE style="BACKGROUND: #e6e6e6"><I><FONT color=#008000>// use local object: 
</FONT></I>X x<B><FONT color=#646464>;</FONT></B> 
A a<B><FONT color=#646464>;</FONT></B> 
std<B><FONT color=#646464>::</FONT></B>string s<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"abc"</FONT><B><FONT color=#646464>);</FONT></B><I><FONT color=#008000> 
// … 
</FONT></I>x<B><FONT color=#646464>.</FONT></B>f<B><FONT color=#646464>(</FONT></B>a<B><FONT color=#646464>,</FONT></B> s<B><FONT color=#646464>);</FONT></B> 
</PRE>2、使用远程代理wrapper层： <PRE style="BACKGROUND: #e6e6e6"><I><FONT color=#008000>// use remote object : 
</FONT></I>proxy<B><FONT color=#646464>&lt;</FONT></B>X<B><FONT color=#646464>&gt;</FONT></B> x<B><FONT color=#646464>;</FONT></B> 
x<B><FONT color=#646464>.</FONT></B>connect<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"my_host"</FONT><B><FONT color=#646464>);</FONT></B> 
A a<B><FONT color=#646464>;</FONT></B> 
std<B><FONT color=#646464>::</FONT></B>string s<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"abc"</FONT><B><FONT color=#646464>);</FONT></B><I><FONT color=#008000> 
// … 
</FONT></I>x<B><FONT color=#646464>.</FONT></B>f<B><FONT color=#646464>(</FONT></B>a<B><FONT color=#646464>,</FONT></B> s<B><FONT color=#646464>);</FONT></B> 
<BR></PRE>
<HR>

<P>仅使用一个包装层就完成远程调用？从目前的C＋＋来看基本上不可能。 今天突然想到可以使用aspect c++来生成代码，因为aspect c++在生成代码时，也生成了一些简单的元信息，可以在函数里面取得函数的原型、各参数的类型等。 根据0x的描述，我编写了简单的测试代码： <PRE style="BACKGROUND: #e6e6e6"><FONT color=#a000a0>#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;vector&gt;
</FONT><B><FONT color=#0000ff>using namespace</FONT></B> std<B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>

class</FONT></B> LoginService<B><FONT color=#646464>
{</FONT></B><B><FONT color=#0000ff>
public</FONT></B><B><FONT color=#646464>:</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> bool</FONT></B> login<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> name<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> password<B><FONT color=#646464>,</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>) =</FONT></B><FONT color=#800080> 0</FONT><B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> void</FONT></B> logout<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>) =</FONT></B><FONT color=#800080> 0</FONT><B><FONT color=#646464>;
};</FONT></B><B><FONT color=#0000ff>

class</FONT></B> RemoteCall<B><FONT color=#646464>
{</FONT></B><B><FONT color=#0000ff>
public</FONT></B><B><FONT color=#646464>:</FONT></B><B><FONT color=#0000ff>
	bool</FONT></B> connect<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B><B><FONT color=#0000ff> char</FONT></B><B><FONT color=#646464>*</FONT></B> host<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> unsigned short</FONT></B> port<B><FONT color=#646464>)
	{</FONT></B>
		cout<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "connect success"</FONT><B><FONT color=#646464> &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> true</FONT></B><B><FONT color=#646464>;
	}</FONT></B><B><FONT color=#0000ff>
	bool</FONT></B> send<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B><B><FONT color=#0000ff> char</FONT></B><B><FONT color=#646464>*</FONT></B> p<B><FONT color=#646464>,</FONT></B> size_t len<B><FONT color=#646464>)
	{</FONT></B>
		cout<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "send: "</FONT><B><FONT color=#646464> &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B>
		cout<B><FONT color=#646464> &lt;&lt;</FONT></B> string<B><FONT color=#646464>(</FONT></B>p<B><FONT color=#646464>,</FONT></B> len<B><FONT color=#646464>) &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> true</FONT></B><B><FONT color=#646464>;
	}</FONT></B><B><FONT color=#0000ff>
	bool</FONT></B> recv<B><FONT color=#646464>(</FONT></B><B><FONT color=#0000ff>char</FONT></B><B><FONT color=#646464>*</FONT></B> p<B><FONT color=#646464>,</FONT></B> size_t len<B><FONT color=#646464>)
	{</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> true</FONT></B><B><FONT color=#646464>;
	}
};</FONT></B><B><FONT color=#0000ff>

class</FONT></B> RemoteLoginService<B><FONT color=#646464> :</FONT></B><B><FONT color=#0000ff> public</FONT></B> LoginService<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> public</FONT></B> RemoteCall<B><FONT color=#646464>
{</FONT></B><B><FONT color=#0000ff>
public</FONT></B><B><FONT color=#646464>:</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> bool</FONT></B> login<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> name<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> password<B><FONT color=#646464>,</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>)
	{</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> false</FONT></B><B><FONT color=#646464>;
	}</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> void</FONT></B> logout<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>)
	{
	}
};</FONT></B><B><FONT color=#0000ff>

int</FONT></B><B><FONT color=#0000ff> main</FONT></B><B><FONT color=#646464>(</FONT></B><B><FONT color=#0000ff>int</FONT></B> argc<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> char</FONT></B><B><FONT color=#646464> *</FONT></B>argv<B><FONT color=#646464>[])
{</FONT></B>
	RemoteLoginService rls<B><FONT color=#646464>;</FONT></B>
	rls<B><FONT color=#646464>.</FONT></B>connect<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"localhost"</FONT><B><FONT color=#646464>,</FONT></B><FONT color=#800080> 3957</FONT><B><FONT color=#646464>);</FONT></B>
	string session<B><FONT color=#646464>;</FONT></B>
	rls<B><FONT color=#646464>.</FONT></B>login<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"lijie"</FONT><B><FONT color=#646464>,</FONT></B><FONT color=#ff00ff> "lijie"</FONT><B><FONT color=#646464>,</FONT></B> session<B><FONT color=#646464>);</FONT></B>
	rls<B><FONT color=#646464>.</FONT></B>logout<B><FONT color=#646464>(</FONT></B>session<B><FONT color=#646464>);</FONT></B><B><FONT color=#0000ff>
	
	return</FONT></B><FONT color=#800080> 0</FONT><B><FONT color=#646464>;
}</FONT></B>
</PRE>
<HR>
现在的目标是加入一个方面，让RemoteLoginService具有远程调用功能。当然由于此处RemoteCall并未实现，所以只要能够把这个调用正确序列化就算完成目标。 这个方面完成后如下： <PRE style="BACKGROUND: #e6e6e6">aspect Remote<B><FONT color=#646464>
{</FONT></B>
	pointcut remote_class<B><FONT color=#646464>() =</FONT></B><FONT color=#ff00ff> "RemoteCall"</FONT><B><FONT color=#646464>;</FONT></B>
	pointcut remote_call<B><FONT color=#646464>() =</FONT></B> derived<B><FONT color=#646464>(</FONT></B>remote_class<B><FONT color=#646464>()) &amp;&amp; !</FONT></B>remote_class<B><FONT color=#646464>();</FONT></B>

	pointcut virtual_methods<B><FONT color=#646464>() =</FONT></B><FONT color=#ff00ff> "% ...::%(...)"</FONT><B><FONT color=#646464>;</FONT></B>

	advice within<B><FONT color=#646464>(</FONT></B>remote_call<B><FONT color=#646464>()) &amp;&amp;</FONT></B> execution<B><FONT color=#646464>(</FONT></B>virtual_methods<B><FONT color=#646464>()):</FONT></B> before<B><FONT color=#646464>(){</FONT></B>
		stringstream ss<B><FONT color=#646464>;</FONT></B>
		ss<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "\tcall:"</FONT><B><FONT color=#646464> &lt;&lt;</FONT></B> JoinPoint<B><FONT color=#646464>::</FONT></B>signature<B><FONT color=#646464>() &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B>
		ss<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "\targuments:"</FONT><B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
		for</FONT></B><B><FONT color=#646464> (</FONT></B>size_t i<B><FONT color=#646464>=</FONT></B><FONT color=#800080>0</FONT><B><FONT color=#646464>;</FONT></B> i<B><FONT color=#646464>&lt;</FONT></B>JoinPoint<B><FONT color=#646464>::</FONT></B>args<B><FONT color=#646464>(); ++</FONT></B>i<B><FONT color=#646464>)
		{</FONT></B>
			string arg<B><FONT color=#646464>(</FONT></B>tjp<B><FONT color=#646464>-&gt;</FONT></B>argtype<B><FONT color=#646464>(</FONT></B>i<B><FONT color=#646464>));</FONT></B><B><FONT color=#0000ff>
			if</FONT></B><B><FONT color=#646464> (</FONT></B>arg<B><FONT color=#646464>.</FONT></B>find<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"basic_string"</FONT><B><FONT color=#646464>) !=</FONT></B> arg<B><FONT color=#646464>.</FONT></B>npos<B><FONT color=#646464>)
			{</FONT></B>
				ss<B><FONT color=#646464> &lt;&lt; *(</FONT></B>string<B><FONT color=#646464>*)</FONT></B>tjp<B><FONT color=#646464>-&gt;</FONT></B>arg<B><FONT color=#646464>(</FONT></B>i<B><FONT color=#646464>) &lt;&lt;</FONT></B><FONT color=#ff00ff> "|"</FONT><B><FONT color=#646464>;
			}
		}</FONT></B>
		string send_str<B><FONT color=#646464> =</FONT></B> ss<B><FONT color=#646464>.</FONT></B>str<B><FONT color=#646464>();</FONT></B>
		tjp<B><FONT color=#646464>-&gt;</FONT></B>target<B><FONT color=#646464>()-&gt;</FONT></B>send<B><FONT color=#646464> (</FONT></B>send_str<B><FONT color=#646464>.</FONT></B>c_str<B><FONT color=#646464>(),</FONT></B> send_str<B><FONT color=#646464>.</FONT></B>size<B><FONT color=#646464>());
	}</FONT></B>

	advice within<B><FONT color=#646464>(</FONT></B>remote_call<B><FONT color=#646464>()) &amp;&amp;</FONT></B> execution<B><FONT color=#646464>(</FONT></B>virtual_methods<B><FONT color=#646464>()):</FONT></B> after<B><FONT color=#646464>(){</FONT></B>
		vector<B><FONT color=#646464>&lt;</FONT></B><B><FONT color=#0000ff>char</FONT></B><B><FONT color=#646464>&gt;</FONT></B> buffer<B><FONT color=#646464>(</FONT></B><FONT color=#800080>1024</FONT><B><FONT color=#646464>,</FONT></B><FONT color=#ff00ff> '\0'</FONT><B><FONT color=#646464>);</FONT></B>
		tjp<B><FONT color=#646464>-&gt;</FONT></B>target<B><FONT color=#646464>()-&gt;</FONT></B>recv<B><FONT color=#646464> (&amp;(*</FONT></B>buffer<B><FONT color=#646464>.</FONT></B>begin<B><FONT color=#646464>()),</FONT></B> buffer<B><FONT color=#646464>.</FONT></B>size<B><FONT color=#646464>());</FONT></B><I><FONT color=#008000>
		// 解析接收的数据，远程调用结果写入tjp-&gt;result()指向的内存
</FONT></I><B><FONT color=#646464>	}
};</FONT></B></PRE>
<HR>
它匹配所有从RemoteCall上派生的类，为它的每个方法加入远程调用代码以及调用结果处理代码。 生成并编译运行，输出如下： <BR>connect success <BR>send: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call:bool RemoteLoginService::login(const ::std::basic_string&lt; char &gt; &amp;,const ::std::basic_string&lt; char &gt; &amp;,::std::basic_string&lt; char &gt; &amp;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arguments:lijie|lijie|| <BR>send: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call:void RemoteLoginService::logout(const ::std::basic_string&lt; char &gt; &amp;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arguments:| <BR><BR>由于完整序列化了各个参数值，第一个目标——生成远程调用代码——算是完成了。 <BR><BR>下一个目标，考虑服务端如何编写？服务端需要开启一个服务，并注册各个服务接口。 <BR><BR>要达到这个目标，aspect c++需要提供类、方法级别的类型及名称获取，不过aspect c++在这方面没有提供更多方便，现在只能在方法执行时获得方法的信息，它所生成的“元信息”过于简单，而且为了效率考虑都实现为各个独立的结构，结构的成员也大都是static的，所以无法使用一个合适的接口来反射，期待以后能加入这些特性。 <BR><BR>所以这第2个目标实际上无法简单地完成，除非在服务端手工添加服务注册代码，这个部分工作量稍小，但还是可以做到的。<img src ="http://www.cppblog.com/cpunion/aggbug/1888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-19 22:50 <a href="http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［C++之AOP］实战Aspect C++之观察者模式</title><link>http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 17 Dec 2005 02:21:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1842.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1842.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1842.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 关于Aspect C++以及AOP，还有许多话题，不过不打算再继续了，AOP是个广泛的议题，局限在某一实现上只会使我们眼界变窄。&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/1842.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-17 10:21 <a href="http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［C++之AOP］实战Aspect C++之检查内存泄漏</title><link>http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 16 Dec 2005 14:38:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1836.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1836.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1836.html</trackback:ping><description><![CDATA[前面简单介绍了Aspect C++，相信没人看出它有什么特别强大的地方。<BR><BR>这次特别挑了一个合适的例子，检查内存泄漏。<BR><BR>首先看一个普通的程序：<BR>1、test.h<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__TEST_H__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__TEST_H__</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1<BR>{<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test2<BR>{<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test3<BR>{<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__TEST_H__</SPAN><SPAN style="COLOR: #000000"><BR></SPAN></DIV>2、main.cc<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test1&nbsp;test1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test2&nbsp;test2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test3&nbsp;test3;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test2();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test2();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1(test1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test3(test3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR></SPAN></DIV><BR>这个程序会有6个对象泄漏。如果是在很隐蔽的地方分配对象，如何能够快速查找出来呢？<BR><BR>采用Aspect C++，我们可以在构造函数和析构函数中插入代码，帮助检查内存泄漏。<BR><BR>首先实现一个内存分配记录管理器：<BR>1、memory_recorder.h<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__MEMORY_RECORDER_H__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__MEMORY_RECORDER_H__</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">map</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typeinfo</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;map</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">*&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;objects;<BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #000000">MemoryRecorder&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;addObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;removeObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder&nbsp;g_memoryRecorder;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__MEMORY_RECORDER_H__</SPAN><SPAN style="COLOR: #000000"><BR></SPAN></DIV>2、memory_recorder.cc<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">memory_recorder.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><BR><BR>MemoryRecorder&nbsp;g_memoryRecorder;<BR><BR><BR>MemoryRecorder::</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #000000">MemoryRecorder&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(objects.size()&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;objects.size()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;objects&nbsp;not&nbsp;released:</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(map</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">*&gt;</SPAN><SPAN style="COLOR: #000000">::const_iterator&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;objects.begin();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;objects.end();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\t</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">second</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">name()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">first)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;(iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">first);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder::addObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;objects.insert(make_pair(obj,&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">ti));<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder::removeObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;objects.erase(obj);<BR>}<BR></SPAN></DIV>3、实现方面，test.ah<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__TEST_AH__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__TEST_AH__</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">memory_recorder.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><STRIKE>#include&nbsp;</STRIKE></SPAN><STRIKE><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN></STRIKE><SPAN style="COLOR: #000000"><BR></SPAN><STRIKE><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN></STRIKE><SPAN style="COLOR: #000000"><STRIKE>&nbsp;std;</STRIKE><BR><BR>aspect&nbsp;MemberRecorder<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;pointcut&nbsp;all_class()&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;classes(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Test%</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;advice&nbsp;construction&nbsp;(all_class())&nbsp;:&nbsp;after&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_memoryRecorder.addObject&nbsp;(tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target(),&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;advice&nbsp;destruction&nbsp;(all_class())&nbsp;:&nbsp;after&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_memoryRecorder.removeObject&nbsp;(tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target(),&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__TEST_AH__</SPAN><SPAN style="COLOR: #000000"><BR></SPAN></DIV><BR>这个方面实现的功能很简单，首先定义了一个pointcut(切面)，它匹配所有以“Test”开头的类。<BR>接下来定义了2个处理方法，分别在这些类的构造函数和析构函数调用之后执行。<BR><BR>tjp-&gt;target()指向Test*对象实例，其它的不详细说明了，应该都比较容易懂。<BR><BR>顺便说一下，前一篇里说源文件可以保存为.cpp文件，实际上是错误的，它只处理.h和.cc文件。<BR><BR>运行ac++产生代码，编译运行后效果如下：<BR>F:\projects\aspectc-out&gt;main<BR>6 objects not released:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test1: 00372B40<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test1: 00372B70<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test3: 00372BA0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test1: 00374F90<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test2: 00374FC0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test2: 00374FF0<BR><BR>另外，产生代码时最好是使用mingw，配置方便一些，不影响产生后的代码，产生后的代码可以使用VC编译。<img src ="http://www.cppblog.com/cpunion/aggbug/1836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-16 22:38 <a href="http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++之AOP</title><link>http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 15 Dec 2005 07:43:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1795.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1795.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1795.html</trackback:ping><description><![CDATA[AOP是近年炒得很热，但却用得很少的一门技术，不过这并不能阻止我去学习它。既然能一度炒得火热，必定有过人之处。说AOP是一种思想或许更适合一些，它并不描述哪一种专有的技术，也不指定实现方式。<BR><BR>众所周知，C++没有丰富的动态类型信息，更没有动态生成类的功能(C++类型在编译后就基本上没有类型存在了)，所以无法像java一样采用动态代理来实现AOP。<BR><BR>Aspect C++是C++的一个AOP实现，它使用了插入代码的方法。<BR><BR>一个典型的Aspect C++示例需要一个C++源文件(.cpp)、一个Aspect C++源文件(.ah)，通过ac++编译器把C++源文件和Aspect C++源文件转换成混合的C++源文件(如果有头文件也会转换)，最后通过普通的C++编译器编译出可执行文件。<BR><BR>下面是一个简单的示例：<BR><BR>1、C++源文件：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">stdio.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A&nbsp;{<BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;b);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;b)&nbsp;{<BR>&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">inside&nbsp;A::a(%d,&nbsp;%f)\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;i,&nbsp;b);<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;i;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;c,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">str)&nbsp;{<BR>&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">inside&nbsp;b(%c,&nbsp;%s)\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;c,&nbsp;str);<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()&nbsp;{<BR>&nbsp;&nbsp;A&nbsp;a;<BR>&nbsp;&nbsp;a.a(</SPAN><SPAN style="COLOR: #000000">4711</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3.14</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;b(</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">H</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ello&nbsp;World</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp; return 0;<BR>}</SPAN></DIV><BR>2、Aspect C++源文件：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">stdio.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR>aspect&nbsp;Action&nbsp;{<BR>&nbsp;&nbsp;advice&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;before(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;after(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;advice&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;before(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;after(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>};<BR><BR>aspect&nbsp;ActionB&nbsp;{<BR>&nbsp;&nbsp;advice&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;before(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;after(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;advice&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;before(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;after(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>};<BR></SPAN></DIV><BR>简单说明一下：<BR>1、“aspect Action”定义了一个“方面”，名字是“Action”，定义一个方面可以理解为“我关注程序的这个方面”。<BR>2、“advice&nbsp;切入点:位置”定义一个“处理方法”，在切入点的指定位置上执行代码。切入点可以选择call、execution、construction、destruction，分别表示调用、执行、构造函数、析构函数。执行点可以选择before、after、around，分别表示在这些切入点的前面、后面或替换掉整个函数。<BR>3、tpj表示thisJoinPoint，表示切入点本身。上面的例子由于使用around替换了整个执行过程，所以要执行原来的操作还需要调用tpj-&gt;proceed()。这里的around完成的功能可由一个before和一个after代替<BR>4、切入点的匹配模式。切入点通过字符串来匹配要切入的操作，“%”字符表示匹配任意类型(或名字)，在AspectJ中，这个字符是“*”，由于C++中“*”用来定义指针，所以在Aspect C++中用“%”；“...”用来匹配任意个参数。<BR><BR>编译：<BR>首先运行ac++ -p&nbsp;&lt;你的源文件所在目录&gt; -d&nbsp;&lt;输出文件目录&gt; -I&lt;附加头文件目录&gt;，这一步会转换C++源文件和Aspect C++源文件。<BR><BR>如果在安装了VC，编译时可指定INCLUDE路径及_WIN32宏。<BR>ac++ -p&nbsp;&lt;你的源文件所在目录&gt; -d&nbsp;&lt;输出文件目录&gt; -I&lt;附加头文件目录&gt; -I"C:\Program Files\Microsoft Visual Studio 8\VC\include" -D_WIN32<BR><BR>然后直接编译：<BR>cl &lt;源文件名&gt;.cc<BR><BR>上面这个程序在处理前运行结果如下：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">F:\soft\ac\examples\Action</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">main<BR>inside&nbsp;A::a(</SPAN><SPAN style="COLOR: #000000">4711</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3.140000</SPAN><SPAN style="COLOR: #000000">)<BR>inside&nbsp;b(H,&nbsp;ello&nbsp;World)</SPAN></DIV><BR>经Aspect C++处理后运行结果：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">F:\soft\ac\examples\Action</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">main<BR>A:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;0012FF73<BR>B:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;0012FF73<BR>A:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;0012FF73<BR>target:&nbsp;0012FF73<BR>B:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;0012FF73<BR>target:&nbsp;0012FF73<BR>inside&nbsp;A::a(</SPAN><SPAN style="COLOR: #000000">4711</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3.140000</SPAN><SPAN style="COLOR: #000000">)<BR>B:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>B:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>B:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>A:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>B:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>inside&nbsp;b(H,&nbsp;ello&nbsp;World)<BR>B:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>B:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)</SPAN></DIV><BR><img src ="http://www.cppblog.com/cpunion/aggbug/1795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-15 15:43 <a href="http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己写的一个max函数</title><link>http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 12 Dec 2005 02:45:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1692.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1692.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1692.html</trackback:ping><description><![CDATA[CSDN上看到有人问能否实现一个效率较高的max函数，效率接近于宏，于是自动动手写了一个。<BR><BR>由于max宏在判断不同类型时，能够返回大的那个类型（表示范围大），所以只能使用模板来进行返回类型的推导。<BR><BR>在VC8上打开O2或Ox优化选项，测试结果是与宏效率相等。<BR><BR>全部实现如下：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typeinfo</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">cassert</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">windows.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">bool</SPAN><SPAN style="COLOR: #000000">&nbsp;B</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;result;<BR>};<BR><BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;BigType</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">sizeof</SPAN><SPAN style="COLOR: #000000">(T)&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">sizeof</SPAN><SPAN style="COLOR: #000000">(U))</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::result&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">,&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">,&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>typename&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::BigType&nbsp;MaX&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;t,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;u)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::BigType&nbsp;ResultType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;ResultType(t&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;u&nbsp;</SPAN><SPAN style="COLOR: #000000">?</SPAN><SPAN style="COLOR: #000000">&nbsp;t&nbsp;:&nbsp;u);&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;原为return&nbsp;(ResultType)t&nbsp;&gt;&nbsp;u&nbsp;?&nbsp;t&nbsp;:&nbsp;u;</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(__int64)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(__int64)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;测试数，需定义在循环外，防止编译器优化掉无意义的循环</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;__int64&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;start&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetTickCount();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">1000000000</SPAN><SPAN style="COLOR: #000000">;&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;MaX(i,&nbsp;(__int64)i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;test必须被使用，否则编译器视为无用数据，会被优化掉</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(GetTickCount()&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;start)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetTickCount();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">1000000000</SPAN><SPAN style="COLOR: #000000">;&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;max(i,&nbsp;(__int64)i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(GetTickCount()&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;start)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV><img src ="http://www.cppblog.com/cpunion/aggbug/1692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-12 10:45 <a href="http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（五）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/28/481.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 28 Sep 2005 14:57:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/28/481.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/481.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/28/481.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/481.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/481.html</trackback:ping><description><![CDATA[本篇没什么清晰的目的，只是解释一下前面的几个问题，并提出一些新的目标。<BR><BR>在“asgard项目遗留问题”中，我简单提到了几个问题，并且想了一些解决方案。<BR><BR>其中，最首要解决的是第2条“服务对象的大小”和第5条“全局元信息”，这2条将影响到调用机制、call对象的生成。一个调用将生成一个call对象，由线程池来处理，同步调用将由异步调用来模拟。<BR><BR>在call对象中，保存了所有in/out参数的包装对象。当处理同步调用时，由于out参数可能是一个栈上对象（或简单类型，这里统称对象），所以需要另一个包装类——outret模板类，它保存out参数的引用。<BR><BR>当同步调用发生时，生成一个call对象（当然out参数的引用已经包含在里面），把这个call对象交给线程池处理，调用的线程阻塞等待调用结束后被唤醒，这就是所谓的异步调用模拟同步调用。由于异步调用被包装起来了，所以在调用者看来跟同步调用没什么区别。当然这个动作并非必要，完全可以不使用模拟，而采用真正的同步调用，只是看到ICE是这么实现的，心痒痒而已。<BR><BR><BR>asgard的目标是把现有的系统功能包装成为服务，所以在通用方面我考虑得比较多。<BR><BR>比如服务端要开放下面这样一个服务：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTT