﻿<?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++博客-高山流水-文章分类-C&amp;C++语言</title><link>http://www.cppblog.com/jzp/category/1436.html</link><description>        -----  要黑就黑彻底</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 17:10:44 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 17:10:44 GMT</pubDate><ttl>60</ttl><item><title>Inside The C++ Object Model 学习笔记--Semantics of Construction, Destructin, and Copy</title><link>http://www.cppblog.com/jzp/articles/14380.html</link><dc:creator>猩猩</dc:creator><author>猩猩</author><pubDate>Mon, 30 Oct 2006 06:42:00 GMT</pubDate><guid>http://www.cppblog.com/jzp/articles/14380.html</guid><wfw:comment>http://www.cppblog.com/jzp/comments/14380.html</wfw:comment><comments>http://www.cppblog.com/jzp/articles/14380.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jzp/comments/commentRss/14380.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jzp/services/trackbacks/14380.html</trackback:ping><description><![CDATA[
		<p>Chapter 5. Semantics of Construction, Destruction, and Copy</p>
		<p>5.1 “无继承” 情况下的对象构造<br />1. 普通类型(和C相同)<br />2. 抽相数据类型<br />3. 为继承作准备</p>
		<p>5.2 继承体系下对象的构造<br />1.  通用继承构造规则<br />     (1) 在成员初始化列表中的data members初始化操作会被放进constructor的函数本身，并以members的声明顺序为顺序。<br />     (2) 如果有一个member没有出现在初始化列表中，但它有一个default constructor，那么default constructor会被调用。<br />     (3) 如果class object 有virtual table pointer(s)， 它(们)必须被设定初始值，指向适当的virtual table(s)。<br />     (4) 在那之前，所有的上一层的base class constructors必须被调用, 以base class的声明顺序为顺序<br />     (5) 在那之前，所有的virtual base class constructors必须被调用，从左到右，从最深到最浅。 </p>
		<p>2. 虚拟继承(virtual Inheritance)<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: #008080"> 1</span> <span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Point3d : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> Point<br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    Point3d( </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0.0</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0.0</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0.0</span><span style="COLOR: #000000"> ) <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">        : Point( x, y ), _z( z ) {} <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    Point3d( </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Point3d</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs ) <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">        : Point( rhs ), _z( rhs._z ) {} <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">    </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">Point3d(); <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    Point3d</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: #0000ff">const</span><span style="COLOR: #000000"> Point3d</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> ); <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z(){ </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> _z; } <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    </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: #008080">13</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> _z; <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000"> }; </span></div>
		<p> <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: #008080"> 1</span> <span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Psuedo C++ Code: <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Constructor Augmentation with Virtual Base class </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> Point3d</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> Point3d::Point3d( Point3d </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> __most_derived,  </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z ) <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( __most_derived </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> ) <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Point::Point( x, y); <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__Point3d </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __vtbl__Point3d; <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__Point3d__Point </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __vtbl__Point3d__Point; <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">_z </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rhs._z; <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"> } </span></div>
		<p> //<br /> 对于如下的继承层次:<br /> class Vertex   : virtual public Point { ... }; <br /> class Vertex3d : public Point3d, public Vertex { ... }; <br /> class PVertex  : public Vertex3d { ... }; </p>
		<p> 类Point3d的构造可能是:</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: #008080"> 1</span> <span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Psuedo C++ Code: <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Constructor Augmentation with Virtual Base class </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> Point3d</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> Point3d::Point3d( Point3d </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> __most_derived,  </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z ) <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( __most_derived </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> ) <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Point::Point( x, y); <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__Point3d </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __vtbl__Point3d; <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__Point3d__Point </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __vtbl__Point3d__Point; <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">_z </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rhs._z; <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"> }</span></div>
		<p> //<br /> 对于Vertex3d的构造可能是如下:</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: #008080"> 1</span> <span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Psuedo C++ Code: <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Constructor Augmentation with Virtual Base class </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> Vertex3d</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> Vertex3d::Vertex3d( Vertex3d </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> __most_derived, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z ) <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( __most_derived </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> ) <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Point::Point( x, y); <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> invoke immediate base classes, <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> setting __most_derived to false </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Point3d::Point3d( </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">, x, y, z ); <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Vertex::Vertex( </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">, x, y ); <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> set vptrs <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #008000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> insert user code </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000"> } </span></div>
		<p> </p>
		<p>3. vptr初始化语意学(The Semantics of the vptr Initialization)<br />     (1) 构造函数执行算法<br />          I.    在derived class constructor 中, 所有的"virtual base classes" 及 "上一层base class"的constructors会被调用. <br />   II.  上述完成之后, 对象的vptr(s)会被初始化, 指向相关的virtual talbe(s).<br />   III. 如果有成员初始化列表的话, 将在constructor体内扩展开来. 这必须在vptr被设定之后才能进行,以免有一个virtual member function被调用<br />   IV. 最后, 执行程序所提供的代码.<br />     <br />     (2) 示例:<br />     For example, given the following user-defined PVertex constructor:</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: #008080">1</span> <span style="COLOR: #000000">PVertex::PVertex( </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z ) <br /></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000">    : _next( </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> ), Vertex3d( x, y, z )<br /></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000">    , Point( x, y ) <br /></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080">5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( spyOn ) <br /></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000">   cerr </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">within Point3d::Point3d()</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> size: </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> size() </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl; <br /></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000"> } </span></div>
		<p> </p>
		<p>  可能一个扩展如下: </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: #008080"> 1</span> <span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Pseudo C++ Code <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> expansion of PVertex constructor </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> PVertex</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> PVertex::PVertex( Pvertex</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: #0000ff">bool</span><span style="COLOR: #000000"> __most_derived, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z ) <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> conditionally invoke the virtual base constructor </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( __most_derived </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> ) <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Point::Point( x, y ); <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> unconditional invocation of immediate base </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Vertex3d::Vertex3d( x, y, z ); <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> initialize associated vptrs </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__PVertex </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __vtbl__PVertex; <br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__Point__PVertex </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __vtbl__Point__PVertex; <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> explicit user code </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( spyOn ) <br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">   cerr </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">within Point3d::Point3d()</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> <br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">   </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> size: </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">__vptr__PVertex[ </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"> ].faddr)(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">) <br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">   </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl; <br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> return constructed object </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">23</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000"> } </span></div>
		<p> </p>
		<p>
				<br />5.3 对象的复制(Object Copy Sematics)<br />1. Copy constructor operator 在以下几种情况下不会表现出: bitwisecopy<br />     (1) class 内带有一个member object, 而其类有一个copy constructor operator时。<br />     (2)  当一个 class 的base 有一个copy assignment operator时。<br />     (3)  当类声明了任何一个virtual functions时。<br />     (4)  当class继承自一个virtual base class时<br /> 2. 合成示例</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: #008080"> 1</span> <span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Pseudo C++ Code: synthesized copy assignment operator </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> inline Point3d</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> Point3d::</span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">( Point3d </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Point3d </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">p ) <br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> invoke the base class instance </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Point::</span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">( p ); <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> memberwise copy the derived class members </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">  _z </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> p._z; <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">  </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 /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"> } </span></div>
		<p> </p>
		<p>5.4 对象的功能</p>
		<p>
				<br />5.5 析构语意学(Semantics of Destruction)<br />1. 析构函数生成原则：<br /> 如果类没有定义destructor, 那么只有在class内带的member object(或是class自己的base class)拥有destructor的情况下，编译器才会自动的合成一个来。否则，destructor会被视为不需要，也就不需要被合成(当然更不需要被调用)</p>
		<p>2. 析构调用过程<br />     (1) destructor的函数本身首先被执行。<br />     (2) 如果class拥有member class objects, 而后者拥有destructors, 那么它会以其声明顺序的相反顺序被调用.<br />     (3) 如果object内带一个vptr， 则现在被重新设定，指向适当的base class的virtual table.<br />     (4) 如果任何直接的(上一层)novirtual base classes 拥有destructor，那么它会以其声明顺序相反的顺序调用<br />     (5) 如果有任何的virtual base classes 拥有destructor， 而当前讨论的这个class是最末端的class， 那么它们会以其原来的构造顺序相反的顺序被调用.</p>
		<p> </p>
<img src ="http://www.cppblog.com/jzp/aggbug/14380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jzp/" target="_blank">猩猩</a> 2006-10-30 14:42 <a href="http://www.cppblog.com/jzp/articles/14380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inside The C++ Object Model 学习笔记--The Semantics of Function</title><link>http://www.cppblog.com/jzp/articles/14379.html</link><dc:creator>猩猩</dc:creator><author>猩猩</author><pubDate>Mon, 30 Oct 2006 06:39:00 GMT</pubDate><guid>http://www.cppblog.com/jzp/articles/14379.html</guid><wfw:comment>http://www.cppblog.com/jzp/comments/14379.html</wfw:comment><comments>http://www.cppblog.com/jzp/articles/14379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jzp/comments/commentRss/14379.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jzp/services/trackbacks/14379.html</trackback:ping><description><![CDATA[
		<p>Chapter 4.  The Semantics of Function: Function 语意学</p>
		<p>4.1 Member 函数的各种调用方式<br />1. Nonstatic Member Function(非静态成员函数)<br />    要做如下的转换: <br />    (1) 改写函数的原形, 安插一个参数到member function中, 用于提供一个存取管道, 使class object 得以调用该函数, 这个额外的指针称之为: this指针.<br />    如:   <br /> Point3d::magnitude()  会转换为:  Point3d::magnitude(Point3d *const  this)</p>
		<p>    (2)  对函数内每一个针对nostatic data member的存取操作改经由this指针来存取.<br />     如: <br />           return sqrt(<br />  this-&gt;_x  *  this-&gt;_x  + this-&gt;y * this-&gt;_y  + this-&gt;_z * this-&gt;_z;<br />    (3)  将对member function 重写一个外部函数, 对函数名称进行"mangling"处理, 使它生成一个独一无二的名称<br />    <br />2. Virtual Member Function(虚拟成员函数)<br />     例如: <br />  ptr-&gt;normalize(); <br />  它将被转化为如下的调用: <br /> ( * ptr-&gt;vptr[ 1 ])( ptr ); <br /> 这里有几点说明：　<br /> i.  vptr是由编译器生成的指针，指向virtual table<br /> ii.  1 这里是virtual table slot 的索引值，它关联到nomalize这个函数<br /> iii.  第二个ptr表示this指针</p>
		<p>3. Static Member Function(静态成员函数)<br />     如果Point3d::normalize()是一个static member function的话，这两个调用会转化为一般的操作：<br />     obj.normalize(); <br />     ptr-&gt;normalize();<br />     转化为：　<br />     // obj.normalize(); <br />     normalize__7Point3dSFv();<br />     // ptr-&gt;normalize();<br />     normalize__7Point3dSfv();</p>
		<p>4.2 Virtual Member Functions(虚拟成员函数)<br />1. 单一继承下的Virtual Functions<br />     一个多态的class object 身上增加两个members:<br /> I.   一个字符串或数字,  表示class的类型<br /> II.  一个指针，指向某个表格，表格中带有程序的virtual function的执行时期地址<br />    对于一个active virtual function包括下面三个内容：　<br />        I.   这个class 所定义的函数实体, 它会改写一个可能存在的base class virtual function 函数实体.<br /> II.  继承自基类的实体，　这是在derived class 决定不改写virtual function 时才会出现的情况<br /> III. 一个pure_virtual_called()函数实体，它既可以扮演pur virtual function的空间保卫者角色,　也可以当做执行期异常函数.</p>
		<p>2. 多重继承下的Virtual Functions<br />    这种继承涉及到要调整this指针，并且要求不止一个vtbl和vptr，同时要好几个这种虚表和指针</p>
		<p>3. 虚拟继承下的Virtual Functions</p>
		<p>
				<br />4.3 函数的效能</p>
		<p>4.4 指向Member Functions的指针(Pointer-to-Member Functions)<br />1. 指向一般成员函数的指针(Nostatic member and novirtual member function)<br />    取一个nostatic member function的地址,  如果该函数是novirtual, 则得到的结果是它在内存中真正的地址, 然而这个地址也不是完全的, 它也需要绑定到某个class object的地址上, 才能够调用该函数. 所有的nostatic member functions都要对象的地址(用this指出).<br />    例如:<br />     double (Point::*pmf)(); // 定义一个成员函数指针<br />      pfm = &amp;Point::y;   // 初始化这个指针为<br />     (ptr-&gt;*pfm)() ;   // 调用为,  编译器转化为: (pfm)(ptr) </p>
		<p>2. 支持"指向Virtual Member Functions"的指针<br />    对于virtual function, 其地址在编译时期是未知的, 所能知道的仅是virtual function在相关的vitual table 中的索引值. 也就是说对于一个virtual member function取其地址, 所能获得的只是一个索引值. <br />    所以如果: <br />    pmf = &amp;Point::z(); // 获得的是索引值,  调用时:<br />    (ptr.-&gt;pmf)()   // 会转化为: (* ptr-&gt;vptr[(int)pfm] (ptr)</p>
		<p>3. 在多重继承下,指向Member Functions的指针<br />     比较复杂,  定义了一个结构支持这们的操作</p>
		<p>4. 指向 Member Functions 指针的效率</p>
		<p>
				<br />4.4 Inline Functions<br />1. inline functions的生成条件</p>
		<p>2. 对形式参数的处理(Formal Arguments)<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: #008080"> 1</span> <span style="COLOR: #000000">inline </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> min( </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j ) <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> i </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> j </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> i : j; <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> } <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000"> and the following three invocations of the inline function:<br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"> inline </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> bar() <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> minval; <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> val1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> val2 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">2048</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"> </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">(1)</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000">minval </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> min( val1, val2 ); <br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000"> </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">(2)</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000">minval </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> min( </span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2048</span><span style="COLOR: #000000"> ); <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000"> </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">(3)</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000">minval </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> min( foo(), bar()</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> ); <br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> minval; <br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000"> } </span></div>
		<p> <br />用下面的方式进行处理: <br />   (1)  直接的参数替换<br /> //(1)     simple argument substitution <br /> minval = val1 &lt; val2 ? val1 : val2; </p>
		<p>   (2) 如果实际参数是一个常量表达式(const expression),  我们就可以在替换前完成对它的求值操作.<br /> //(2)  constant folding following substitution <br /> minval = 1024; <br />   <br />   (3) 带有副作用的实际参数, 引入临时性的对象<br /> //(3)     side-effects and introduction of temporary <br /> int t1; <br /> int t2; </p>
		<p> minval =  ( t1 = foo() ), ( t2 = bar() + 1 ),  t1 &lt; t2 ? t1 : t2; </p>
		<p>3. 对inline函数带有局部变量的处理(Local Variables)<br />    如:<br /> inline int min( int i, int j ) <br /> { <br />  int minval = i &lt; j ? i : j; <br />  return minval; <br /> } <br />    对于如下的调用:<br />    { <br />    int local_var; <br />    int minval; </p>
		<p>    // ... <br />    minval = min( val1, val2 ); <br />     } </p>
		<p>    转换可能的结果是: </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: #008080">1</span> <span style="COLOR: #000000">    { <br /></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> local_var; <br /></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> minval; <br /></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> mangled inline local variable </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">5</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> __min_lv_minval; <br /></span><span style="COLOR: #008080">6</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">7</span> <span style="COLOR: #000000">    minval </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">  ( __min_lv_minval </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">  val1 </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> val2 </span><span style="COLOR: #000000">?</span><span style="COLOR: #000000"> val1 : val2 ),  __min_lv_minval; <br /></span><span style="COLOR: #008080">8</span> <span style="COLOR: #000000">     }</span></div>
		<p> </p>
<img src ="http://www.cppblog.com/jzp/aggbug/14379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jzp/" target="_blank">猩猩</a> 2006-10-30 14:39 <a href="http://www.cppblog.com/jzp/articles/14379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inside The C++ Object Model 学习笔记--The Semantics of Data</title><link>http://www.cppblog.com/jzp/articles/14378.html</link><dc:creator>猩猩</dc:creator><author>猩猩</author><pubDate>Mon, 30 Oct 2006 06:36:00 GMT</pubDate><guid>http://www.cppblog.com/jzp/articles/14378.html</guid><wfw:comment>http://www.cppblog.com/jzp/comments/14378.html</wfw:comment><comments>http://www.cppblog.com/jzp/articles/14378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jzp/comments/commentRss/14378.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jzp/services/trackbacks/14378.html</trackback:ping><description><![CDATA[
		<p>Chapter 3. The Semantics of Data : Data 语义学</p>
		<p>示例代码：<br />class X {}; <br />class Y : public virtual X {}; <br />class Z : public virtual X {}; <br />class A : public Y, public Z {}; </p>
		<p>
				<br />一个类对象的大小受三个因素的影响<br />i.   语言本身所造成的额外负担(overhead),  当语言要支持virtual base class 时，就会导致一些额外的负担.<br />ii.  编译器对特殊情况所提供的优化处理,  如virtual base class class X subobject 的1bytes大小会出现在子类Y, Z的身上.<br />      如: sizeof(Y) = sizeof(Z) = 4(8) // 这里的4(8)和编译器相关<br />      <br />      有时候有的编译器会用empty virtual base class 技术来优化, VC就是采用这一技术的, 这样virtual base class 就不用占用大小了. </p>
		<p>iii.  Alignment 的限制, Y和Z的大小本来大小都是4, 加上virtual base subobject的1bytes的大小共5个字节, 但实际上去是8bytes，这里就是受到字节对齐的影响.</p>
		<p>C++对象模型对数据的存放结构是: <br />i.   把nonstatic data members直接的放在class object之中, 对继承(不管是virtual 或 nonvirtual base class )而来的nonstatic data members也是这一样的.<br />ii.  没有强制定义其间的排列顺序<br />iii. 对static data members, 则被放置在一个global data segment中, 不会影响单个类的大小, 并且只保存一份实体. (template有所不同)</p>
		<p>3.1 Data Member的绑定(The Binding of Data Member)<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: #008080"> 1</span> <span style="COLOR: #008000">//</span><span style="COLOR: #008000"> A third party foo.h header file <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> pulled in from somewhere </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">extern</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x; <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> the programmer's Point3d.h file </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Point3d <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    Point3d( </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> ); <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> question:  which x is returned and set? </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> X() </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> { </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> x; } <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> X( </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> new_x ) </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> { x </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> new_x; } <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">    </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: #008080">17</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, y, z; <br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000"> }; <br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000"></span></div>
		<p>
				<br /> 在早期的编译器中会出错, 不过在 C++2.0后就不会了, 在C++2.0后, 采用的是"rewriting rule" == "member scope rsolution rule" 规则来处理它. <br /> 以前的编译器中, float X() const { return x; }, 它不知道要返回哪一个x, 这里它会返回全局的 extern float x, 所以是不正确的. 后来的编译器是会在整个class的声明都出现了后才会分析member functions, 所以它不会现错.</p>
		<p> 对于下面的例子还是会出错, 因为对于member functions signatures的分析不会到类完成以后, 而是第一次出现的时候就会分析的. 如下面的:</p>
		<p>  所以最好始终的把"nested type declare" 放在类的起始处. (这在STL中好像最明显, 都是先声明的)</p>
		<p>
				<br />3.2 Data Member的布局 (Data Member Layout)</p>
		<p>示例代码: </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: #008080"> 1</span> <span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Point3d { <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </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: #008080"> 5</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x; <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Point3d</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">freeList; <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y; <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> chunkSize </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">250</span><span style="COLOR: #000000">; <br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z; <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"> }; <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"></span></div>
		<p>      Data Member的布局按如下的规则: <br />      i.   Nonstatic data member 在class object中的排列顺序和被声明的顺序是一样的, 任何中间介入的static data member都不会被放进对象的布局中. <br />      ii.  要求在同一access section中"较晚出现的members在class object中有较高的地址"这一条件就可以. <br />      iii. 编译器可能会合成一些内部使用的data members, 以支持整个对象模型, 如vptr指针.  对于它的具体位置, C++ Standard 没有规定, 由编译器产商自己决定. 不过传统上一般是放在所有声明的members的最后, 也有把vptr放在所有class object的最前端的. </p>
		<p>
				<br />3.3 Data Member的存取<br />示例:<br />      Point3d origin, *pt = &amp;origin;<br />      origin.x    = 0.0;<br />      pt-&gt;x = 0.0</p>
		<p>1. Static Data Members的存取<br />    每一个static data member只有一个实体，存在于程序的data segment中。每次程序取用这个static data member的时候，就会被转化为对该实体的唯一的extern实体的直接参考操作.  用指针存取一个数和用对象去存取一个数是一样的。<br />     <br />2. Nostatic Data Members的存取<br />    Nostatic data member 直接存放在每一个class object之中，除非经由明确的或暗喻的class object，否则没有办法直接的存取它们。<br />    例如:<br />    Point3d  Point3d::translate( const Point3d &amp;pt )<br />    { <br />    x += pt.x; <br />    y += pt.y; <br />    z += pt.z; <br />    } <br />    实际经过转换后为：<br />    Point3d  Point3d::translate( Point3d *const this, const Point3d &amp;pt )<br />    { <br />     this-&gt;x += pt.x; <br />    this-&gt;y += pt.y; <br />    this-&gt;z += pt.z; <br />    } <br />    对nostatic data member的访问是这样的:  <br /> origin._y = 0.0;  <br />    实际转换操作是: <br />        &amp;origin + (&amp;Point3d::_y - 1 );<br />       <br />       注意:  这里的-1操作。指向data member的指针，其offset值总是被加上1， 这样可以使编译系统区分出:<br /> i.  一个用以指出class的第一个member的data member的指针.<br /> ii. 一个没有指出任何member的data member的指针.<br />   <br />    如果是virtual 继承的话，就可以不一样了，可能要多加层的访问层; 也可能要到运行时才能决定，由编译器所决定.</p>
		<p>
				<br />3.4 “继承”与Data Member<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: #008080"> 1</span> <span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> supporting abstract data types </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Point2d<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> constructor(s) <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #008000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> operations <br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> access functions </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, y; <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"> }; <br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"> </span><span style="COLOR: #808080">///</span><span style="COLOR: #008000"> </span><span style="COLOR: #808080"><br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #808080"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Point3d<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> constructor(s) <br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #008000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> operations <br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #008000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> access functions </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x, y, z; <br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000"> }; <br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000"></span></div>
		<p>    C++的继承模型: <br /> 在C++的继承模型中， 一个derived class object 所表现出来的东西，是其自己的member加上其base class(es) member的总和。对于数据成员出现的顺序在C++ Standard 中没有规定。从下面几个方面来讨论数据继承:<br /> i.   单一继承且不含有virtual functions<br /> ii.   单一继承并含有virtual functions<br /> iii.  多重继承<br /> iV. 虚拟继承</p>
		<p>1. 只要继承不要多态(Inheritance Without Polymoophism)<br />    继承一般不会增加空间或存取时间。但继承有时会有这样两种情况出现:<br />    i.   经验不足的人有时可能会重复的设计一些相同的函数.<br />    ii.  把一个类分解为多层，有可能会为了表现class的体系抽象化，使所需要的空间膨胀。<br />        因为C++语言要保证: 出现在derived class 中的base class subobject 有其完整原样性。</p>
		<p>2. 加上多态(Adding Polymorphism)<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: #008080"> 1</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Point2d <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"> { <br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    Point2d( </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> x </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0.0</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> y </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0.0</span><span style="COLOR: #000000"> ) <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">       : _x( x ), _y( y ) {}; <br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> access functions for x &amp; y same as above <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> invariant across type: not made virtual <br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000">  <br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #008000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> add placeholders for z ?do nothing <img src="http://www.cppblog.com/images/dot.gif" /> </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> z(){ </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0.0</span><span style="COLOR: #000000"> }; <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> z( </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> ) {} <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> turn type explicit operations virtual </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</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"> Point2d</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs )<br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">    { <br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">        _x </span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000"> rhs.x(); _y </span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000"> rhs.y();<br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">     } <br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">  <br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" /> more members </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">23</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> _x, _y; <br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000"> }; <br /></span><span style="COLOR: #008080">25</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">26</span> <span style="COLOR: #000000"></span></div>
		<p>
				<br /> // <br /> 要支持多态，Point2d数据成员要做如下的工作:<br /> i.   导入一个和Point2d有关的virtual table(vtbl), 存放它声明的每一个virtual function的地址 <br /> ii.   在每个class object中导入一个vptr, 提供执行期的链接，使每个object都能找到相应的virtual table.<br /> iii.  加强construtor, 使它能够为vptr设定初值，让它指向class所对应的virtual table. <br /> iV.  加强destructor, 使它能够抹消"指向class的相关"virtual table" 的vptr.</p>
		<p> Figure 3.3. Data Layout: Single Inheritance with Virtual Inheritance<br /> </p>
		<p>3. 多重继承(Multiple Inheritance)<br /> <br /> <br />4. 虚拟继承(Virtual Inheritance)<br />    Class 中如果含一个或多个virtual base class subobjects, 它将被分为两个部分: 一个不变的局部和一个共享的局部. <br />    i.   不变的局部中的数据，不管后继如何衍化，总有固定的offset， 所这一部分的数据可以直接的被存取。 <br />    ii.  共享的局部，所表现的就是virtual base class subobject, 这一部分的数据会因为每次派生的操作而有变化, 所以它们只能间接的存取。</p>
		<p>
				<br />3.5 对象成员的效率(Object Member Efficiency)</p>
		<p>3.6 指向数据成员的指针(Point to Data Members)</p>
<img src ="http://www.cppblog.com/jzp/aggbug/14378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jzp/" target="_blank">猩猩</a> 2006-10-30 14:36 <a href="http://www.cppblog.com/jzp/articles/14378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inside The C++ Object Model 学习笔记 -- The Semantics Of Constructors</title><link>http://www.cppblog.com/jzp/articles/14377.html</link><dc:creator>猩猩</dc:creator><author>猩猩</author><pubDate>Mon, 30 Oct 2006 06:33:00 GMT</pubDate><guid>http://www.cppblog.com/jzp/articles/14377.html</guid><wfw:comment>http://www.cppblog.com/jzp/comments/14377.html</wfw:comment><comments>http://www.cppblog.com/jzp/articles/14377.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jzp/comments/commentRss/14377.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jzp/services/trackbacks/14377.html</trackback:ping><description><![CDATA[
		<p>2.1 Default Constructor 的构造操作<br />    按照C++ Annotated Reference Manaual 的说法："Default constructor... 在需要的时候被编译器产生出来". 这里的关键字是：“在需要的时候”。 <br />    C++ Standard[ISO-C++95]中又有如下的声明：对于class X, 如果没有任何user-declared constructor，那么会有一个default constructor 被暗中声明出来....一个被暗中声明出来的default constructor 将是一个trival的constructor"。 这里我觉得主要是“user-declared constructor”，它包括用户所定义的所有的constructor还有其它的一些有virtual关键字的操作。这样下面的四种情况下由编译器生成的constructor是notrival default constructor：<br />    <br />    1. 带有 Default Constructor 的 Member Class Object(带有缺省构造函数的类成员对象)<br />    如果一个类的带有一个或多个的类成员对象，而类成员对象又有构造函数，那么就会生成该类就会生成一个notrival default constructor 构造函数。 成员对象的构造函数的调用是按成员对象的声明顺序执行的。例如：<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">
				<img id="Codehighlighter1_10_38_Open_Image" onclick="this.style.display='none'; Codehighlighter1_10_38_Open_Text.style.display='none'; Codehighlighter1_10_38_Closed_Image.style.display='inline'; Codehighlighter1_10_38_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
				<img id="Codehighlighter1_10_38_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_10_38_Closed_Text.style.display='none'; Codehighlighter1_10_38_Open_Image.style.display='inline'; Codehighlighter1_10_38_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Foo </span>
				<span id="Codehighlighter1_10_38_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_10_38_Open_Text">
						<span style="COLOR: #000000">{ </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">: Foo(), Foo(</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">) . }</span>
				</span>
				<span style="COLOR: #000000">;<br /><img id="Codehighlighter1_51_81_Open_Image" onclick="this.style.display='none'; Codehighlighter1_51_81_Open_Text.style.display='none'; Codehighlighter1_51_81_Closed_Image.style.display='inline'; Codehighlighter1_51_81_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_51_81_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_51_81_Closed_Text.style.display='none'; Codehighlighter1_51_81_Open_Image.style.display='inline'; Codehighlighter1_51_81_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Bar </span>
				<span id="Codehighlighter1_51_81_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_51_81_Open_Text">
						<span style="COLOR: #000000">{ </span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">: Foo foo; </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">str; }</span>
				</span>
				<span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> foo_bar()<br /><img id="Codehighlighter1_103_206_Open_Image" onclick="this.style.display='none'; Codehighlighter1_103_206_Open_Text.style.display='none'; Codehighlighter1_103_206_Closed_Image.style.display='inline'; Codehighlighter1_103_206_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_103_206_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_103_206_Closed_Text.style.display='none'; Codehighlighter1_103_206_Open_Image.style.display='inline'; Codehighlighter1_103_206_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_103_206_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_103_206_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />       Bar bar; </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> Bar::foo在这里被初始化(调用Foo的缺省构造行数: Foo:Foo())<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />      <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />      </span>
						<span style="COLOR: #008000">//<br /><img id="Codehighlighter1_195_197_Open_Image" onclick="this.style.display='none'; Codehighlighter1_195_197_Open_Text.style.display='none'; Codehighlighter1_195_197_Closed_Image.style.display='inline'; Codehighlighter1_195_197_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_195_197_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_195_197_Closed_Text.style.display='none'; Codehighlighter1_195_197_Open_Image.style.display='inline'; Codehighlighter1_195_197_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span>
						<span style="COLOR: #000000">     </span>
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000"> (str) </span>
						<span id="Codehighlighter1_195_197_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_195_197_Open_Text">
								<span style="COLOR: #000000">{ }</span>
						</span>
						<span style="COLOR: #000000">  . <br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />   }</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
		</div>
		<p>    <br />    对于有多个成员对象的类，则按成员对象在类的声明中的顺序调用它们的构造函数。<br />       <br />    2. 带有 Default Constructor 的 Base Class(带有缺省构造函数的基类对象)       指的是一个没有任何constructorsrs的类派生自一个带有“default constructor”的基类。 如果类存在多个构造函数的话，那么编译器也会扩充现有的每一个构造函数，将调用基类的default constructor的代码加入到其中。 <br />        <br />    3. 带有一个 Virtual Function 的 Class <br />    这样的virtual Function可以使继承来的或直接定义的。 编译器在编译期间会做如下工作<br />    a. 生成一个virtual Function talbe(vtbl), 用来存放class 的virtual function的地址<br />    b. 在每一个class object中，添加一个额外的pointer member(vptr)，它指向class vtbl的地址<br />    <br />    4. 带有一个 Virtual Base Class 的 Class<br />    这种情况是在导出类的安插一个virtual base classes的指针，用来在运行时存取virtual base class 的成员。例如：<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: #008080"> 1</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> X { </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i; }; <br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> A : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> X   { </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j; }; <br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> B : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> X   { </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> d; }; <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> C : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> A, </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> B { </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> k; }; <br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> cannot resolve location of pa-&gt;X::i at compile-time </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo( </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> A</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pa ) { pa</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">; } <br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 在编译期可能生成如下形式:<br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> void foo(const A* pa) { pa-&gt;_vbcX-&gt;i = 1024; } </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> _vbcX: virtual base class X</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    <br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    main() <br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    { <br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">        foo( </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> A ); <br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">        foo( </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> C ); <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000">    <br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">        </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: #008080">17</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000"></span></div>
		<p>    <br />    注意:　在合成的default constructor中，只有base class subobjects和member class objects会被初始化，其它所有的nostatic data member都不会执行初始化的操作．要我们自己手动的去执行初始化的操作．</p>
		<p>    其实把握一个原则：要不要合成一个构造函数，依据编译器的需要与否，合成出来的constructor也只是完成那些编译器所需求。<br />    <br />    两个错误的观点：<br /> i. 任何时候，如果没有定义default constructor，就会被合成一个出来。(而是根据编译器的需要决定是否生成一个deault constructor)<br /> ii. 编译器生成出来的default constructor会明确的初始化每类中的每一个data member. </p>
		<p>
				<br />2.2 Copy Constructor的构建操作<br />    有三种情况下会有一个Copy Constructor的操作：<br /> i.   对一个object做明确的初始化操作  // class X{ ....};   X x;    X xx = x;<br /> ii.  当某个object作为参数传递给某个函数  // void foo(X x) { .... }<br /> iii. 函数传回一个class object对象  // void foo(){ X xx; return xx;}</p>
		<p>    1. Default Memberwise Initialization(缺省的按成员初始化)<br />    如果一个类没有explicit copy constructor时, class object在执行copy constructor时，内部以default member initialization的手法来完成，就是把每一个内建或者派生而来的data member的值从某个object 拷贝一份到另一个object身上，对member class object是以递归的方式调用memberwise initialization的。<br />    <br />    这种初始化是通过在必要时生成一个copy constructor或通过 bitwise copy 来完成的。 如果要通过bitwise来完成这这样的操作，那么必须表现出bitwise copy semantise.  <br />    <br />    C++ Standard中也把copy constructor分成trial 和notrivial两种类型，只有notrivial的实体才会被合成于程序中。决定一个copy constructor是否为trivial在于类是否表现出所谓的"Bitwise copy sematics".<br />    <br />    2. Bitwise Copy Semantics<br />    在 bitwise copy sematics 下，不会构造出一个default copy constructor. 例如：<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: #008080"> 1</span> <span style="COLOR: #000000">   </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Word<br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000">    {<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">        Word(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">        </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">Word(){ delete []str; }<br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">        </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: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> cnt;<br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">str;<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    }  <br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    以上的是一个表现出Bitwise copy sematics的类，而以下是一个没有表现出bitwise copy sematics的类<br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Word<br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    {<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000">        Word(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">        </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">Word(){ delete []str; }<br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">        </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: #008080">18</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> cnt;<br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">        String str;<br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">    <br /></span><span style="COLOR: #008080">23</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> String <br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000">    {<br /></span><span style="COLOR: #008080">25</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: <br /></span><span style="COLOR: #008080">26</span> <span style="COLOR: #000000">        String(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">27</span> <span style="COLOR: #000000">        String(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> String的显示copy constructor</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">28</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">        </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">String();<br /></span><span style="COLOR: #008080">29</span> <span style="COLOR: #000000">        </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: #008080">30</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">31</span> <span style="COLOR: #000000">    这种情况下会合成一个copy constructor以调用class String object的copy constructor.<br /></span><span style="COLOR: #008080">32</span> <span style="COLOR: #000000">    inline Word::Word(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Word</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> wd)<br /></span><span style="COLOR: #008080">33</span> <span style="COLOR: #000000">    {<br /></span><span style="COLOR: #008080">34</span> <span style="COLOR: #000000">        str.String::String(wd.str);<br /></span><span style="COLOR: #008080">35</span> <span style="COLOR: #000000">        cnt </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> wd.cnt;<br /></span><span style="COLOR: #008080">36</span> <span style="COLOR: #000000">    }    <br /></span><span style="COLOR: #008080">37</span> <span style="COLOR: #000000"></span></div>
		<p>       <br />    3. 不表现出Bitwise Copy Sematics的特性的情况<br />    以下的几种情况class不表现出 Bitwise Sematics:<br />        a. 当class 内含有一个member object, 而后者的class 声明有一个copy constructor时(合成或声明的都可以)，就不表现出Bitwise Sematics<br />        b. 当class 继承自一个base class, 而后者存在有一个copy constructor(合成或声明的都可以), 就不表现出Bitwise Sematics.<br />        c. 当类声明了一个或多个virtual function时<br />        d. 当class派生自一个继承创串链，其中有一个或多个virtual base classes时, 类就不表现出Bitwise Sematics<br />    这四种情况和default constructor生成的是否一个trivial是一样的, 也是满足编译器的需求。<br />       <br />    4. 重新设定Virtual Table 的指针<br />    对于以上：当类声明了一个或多个virtual function的情况，程序会为类对象做如下两个扩张操作：<br />        (1) 增加一个vtbl的指针，内含virtual function的指针地址。<br />        (2) 在类对象内安插一个vptr指针，指向virtual function table.<br />    对于把一个base class object 以其derived class object的值初始化操作的时候，会发生切割(sliced)操作。这时也要保证vtbl的正确和vtpr的正确性。<br />    <br />    5. 处理Virtual Base Class Subobject<br />    如果一个class object是以另外一个object作为初始值的话，而后者又有一个virtual base class suboject的话，那么也会使bitwise copy sematics失效。例如：<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: #008080"> 1</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Raccoon : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> ZooAnimal{<br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">  Raccoon(){ <img src="http://www.cppblog.com/images/dot.gif" /><img src="http://www.cppblog.com/images/dot.gif" /> ; }<br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">  Raccoon(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> val) { <img src="http://www.cppblog.com/images/dot.gif" /><img src="http://www.cppblog.com/images/dot.gif" />; }<br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    };<br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> RedPanda : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Raccoon{<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">  RedPanda() { <img src="http://www.cppblog.com/images/dot.gif" /><img src="http://www.cppblog.com/images/dot.gif" />.; }<br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">  RedPanda(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> val) { <img src="http://www.cppblog.com/images/dot.gif" /><img src="http://www.cppblog.com/images/dot.gif" />.; }<br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    };<br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">    执行如下操作时会要求合成一个copy constructor:<br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">    RedPanda little_red;<br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">    Raccoon little_critter </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> little_re;  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 这里编译器必须明确的把little_critter的virtual base class pointer/offset初始化。<br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #008000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 如果只是这样的操作用bitwise copy 就可以了</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    Raccoon rocky;<br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">    Raccoon little_critter </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rocky;   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 用简单的bitwise copy 就可以搞定了</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">23</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000"></span></div>
		<p>
				<br />2.3 程序转化语义学(Program Transformation Semantics)<br /> 指的是程序在执行的是候要做的类型和操作的转换。 下面例子反映了三种转换操作：</p>
		<p> </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: #008080"> 1</span> <span style="COLOR: #000000"> #include </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">X.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"> X foo( X x0)<br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  X xx;<br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" />., 对xx和x0进行操作</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> XX;<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"> }<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000"></span></div>
		<p> </p>
		<p> 1. 明确的初始化操作(Explicit Initialization)<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: #008080">1</span>
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">X x0<br /></span>
				<span style="COLOR: #008080">2</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> foo_bar()<br /></span>
				<span style="COLOR: #008080">3</span>
				<span style="COLOR: #000000">
						<img id="Codehighlighter1_22_66_Open_Image" onclick="this.style.display='none'; Codehighlighter1_22_66_Open_Text.style.display='none'; Codehighlighter1_22_66_Closed_Image.style.display='inline'; Codehighlighter1_22_66_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_22_66_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_22_66_Closed_Text.style.display='none'; Codehighlighter1_22_66_Open_Image.style.display='inline'; Codehighlighter1_22_66_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span>
				<span id="Codehighlighter1_22_66_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_22_66_Open_Text">
						<span style="COLOR: #000000">{<br /></span>
						<span style="COLOR: #008080">4</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />  X x1(x0);<br /></span>
						<span style="COLOR: #008080">5</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />  X x2 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> x0;<br /></span>
						<span style="COLOR: #008080">6</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />  X x3 </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> X(x0);<br /></span>
						<span style="COLOR: #008080">7</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> }</span>
				</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #008080">8</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
		</div>
		<p> <br /> 对程序做两个阶段的转化：<br /> i. 重写每一个定义，其中的初始化操作都会被剥除<br /> ii. 类的Copy constructor操作会被安插进去<br /> 转化后可能成为这样的(伪码)：<br /> 这也就是说前面三种的初始化操作都会转换成Explicit Initialization.<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: #008080"> 1</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo_bar()<br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">  X x1; <br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">  X x2;<br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">  X x3;<br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">  x1.X::X(x0);<br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">  x2.X::X(x0);<br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">  x3.X::X(x0);<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"> }<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"></span></div>
		<p> 2. 参数的初始化(Argument Initialization)<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: #008080"> 1</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(X x0){ <img src="http://www.cppblog.com/images/dot.gif" />; }<br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> call()<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">  X xx;<br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" />. xxx 初始化及其操作</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">  foo(xx);<br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000"> }<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"> 转换后的操作为：<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> call()<br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">  X xx;<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000">  X __temp0;<br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">  __temp0.X::X(xx);<br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">  foo(__temp0);                </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> foo 函数应变成：void foo(X&amp; x0);</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">  __temp0.X::</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">X();  <br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000"> }<br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000"></span></div>
		<p> 这就是为什么当传值到孙数的时候，不会把函数内对传入值的操作结果不会被修改，因为它在函数内本来修改的就不是外部传人的那个变量。</p>
		<p>
				<br /> 3. 返回值的初始化(Return Value Initialization)<br /> 例如： <br /> X bar()<br /> {<br />  X xx;<br />  // ....<br />  return xx;<br /> } <br /> <br /> 转化为如下伪码:<br /> void bar(X&amp; __result)<br /> {<br />  X xx;<br />  xx.X::X();   // 编译器生成的一个缺省的构造函数调用</p>
		<p>  // 处理 .... </p>
		<p>  __result.X::X(xx);    // 编译器生成的copy constructor调用操作<br />  return;<br /> }<br /> <br /> 如下的操作转化为：<br /> void foo()<br /> {<br />  X xx = bar(); <br /> }</p>
		<p> 被转化为：<br /> void foo()<br /> {<br />  X xx;<br />  bar(xx);   // 注意这里不用执行 default constructor<br /> }<br /> <br /> 针对这种转换，可以从使用层面上进行优化和在编译器层面上做优化操作。在编译器层面上的操作就是采用NRV(Named Return Value)技术。<br /> 如：<br /> x bar()<br /> {<br />  X xx;<br />  // ....<br />  return xx;<br /> }<br /> 优化为：<br /> void bar(X&amp; __result)<br /> {<br />  __result.X::X();</p>
		<p>  //....  直接的处理 __result</p>
		<p>  //<br />  return ;<br /> } </p>
		<p>2.4 成员初始化队伍(Member Initialization List)<br /> 这里有两点要注意：<br /> 1. 以下的四种情况下必须使用 member intialization list<br />  I.   当初始化一个reference member时<br />  II.  当初始化一个const member时<br />  III. 当初始化一个base class 的constructor，而它拥有一组参数时<br />  IV.  当调用一个member class的constructor, 而它拥有一组参数时</p>
		<p>  其它情况下可以用在构造函数内初始化也可以<br /> <br /> 2. 关于初始化的次序问题：<br />  编译器的初始化的顺序是按member声明次序来依次的初始化的。它会安插一些代码到构造函数内，并放在任何其它用户初始化的代码之前.</p>
		<p> </p>
<img src ="http://www.cppblog.com/jzp/aggbug/14377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jzp/" target="_blank">猩猩</a> 2006-10-30 14:33 <a href="http://www.cppblog.com/jzp/articles/14377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inside The C++ Object Model 学习笔记 -- 关于对象</title><link>http://www.cppblog.com/jzp/articles/5826.html</link><dc:creator>猩猩</dc:creator><author>猩猩</author><pubDate>Tue, 18 Apr 2006 09:31:00 GMT</pubDate><guid>http://www.cppblog.com/jzp/articles/5826.html</guid><wfw:comment>http://www.cppblog.com/jzp/comments/5826.html</wfw:comment><comments>http://www.cppblog.com/jzp/articles/5826.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jzp/comments/commentRss/5826.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jzp/services/trackbacks/5826.html</trackback:ping><description><![CDATA[
		<p>
				<font color="#000000" size="4">
						<strong>一. C/C++ 语言中的方法和数据</strong>
				</font>
				<br />
				<br />    <strong>1. C语言的数据和方法</strong>     语言中数据和处理(函数)是分开的，语言本身不支持数据和函数的关联性。这种方法我们称之为：程序性的；它是由"分布在各个以功能为导向的函数中"d的算法所驱动，它们处理的是共同的数据。</p>
		<p>     <strong>2. C++语言数据和方法</strong><br />     C++中是通过ADT(Abstract Data Type, ADT)来实现的。 C++可以在不同层次上进行抽象，造成的复杂度可能也不一样。<br />     书中从简单到复杂四个层次的抽象: 简单类、继承、一个参数的Template、两个参数的模板。<br /></p>
		<p>
				<font size="4">
						<strong>
								<br />二.C++加上封装后的布局成本(Layout Costs for Adding Encapsulation)<br /></strong>
				</font>
				<br />    <strong>1. C++中的对象的布局</strong><br />    a. data member:  直接的包涵在每一个class object(注意: 类对象，不是类)之中，这和C struct的情况是一样的<br />    b. member function: 它不出现在class object 之中.<br />       non-inline member: 它会产生一个行数的实体. 如果是非static的funciton, 每个function会加上一个this指针作为function的第一个参数.<br />       inline member: 会在每一个使用者身上产生一个函数的实体。这一般是为了提高效率。<br />    <br />    <strong>2. C++布局和存取上的额外开销<br /></strong>    a. virtual function 机制: 用以支持一个有效的"执行期绑定(runtime binding)"  <br />    b. virtual base class<br /><br /><font size="4"><strong><br />三. C++对象模型(The C++ Object Model)<br /><br /></strong></font>    <strong>1. 简单对象模型(A Simple Object Model)<br /></strong>    这种模型中，每个object是一系列的slots, 每个slot指向一个member. 每个member按其申明的次序各占用一个slot. 这里的member包括data member 和 function member. 每个member是通过slot的索引来访问的。<br />    具体的模型参看: <br />    <img height="318" alt="1.1 Simple Object Model.JPG" src="http://www.cppblog.com/images/cppblog_com/jzp/Inside%20The%20C++%20Object%20Model/1.1%20Simple%20Object%20Model.JPG" width="374" border="0" /></p>
		<p>    <strong>2. 表格驱动模型(A Table-driven Object Model)<br /></strong>    这种模型中把class object的members分组放在一个data member table 和一个function member table中，class object内含两个指向table的指针. member function table 是一系列的slots, 每个slot指向一个function member. data member table 则是直接的包涵有data本身。<br />    具体的模型参看: <br />    <img title="1.5 Layout of Object and Pointer of Derived Class" height="294" alt="1.2 Member Table Object Model.JPG" src="http://www.cppblog.com/images/cppblog_com/jzp/Inside%20The%20C++%20Object%20Model/1.2%20Member%20Table%20Object%20Model.JPG" width="374" border="0" /></p>
		<p>    <strong>3. C++对象模型(The C++ Object Model)<br /></strong>    C++的对象模型如下:<br />    a. nostatic data members 被直接的配置在每一个class object之内。<br />    b. static data member 、static 和 nonstatic function members全部被放在所有的class object 之外。<br />    c. virtual functions 则是以下列步骤支持的： <br />        i. 每一个class 产生一堆指向virtual functions的指针，放在表格之中，我们称这个表格为：virtual table(vtbl).<br /> ii. 每个得class object 被添加了一个指针，指向相关的virtual table，我们把class object的这个指针称之为vptr(virtual pointer)；这个vptr的设定和重置是由类的constructor、destructor 和 copy assignment 运算符自动完成的；每个类的type_info object也是经由virtual table指出的，通常是放在表格的第一个slot处。<br />    具体的模型参看: <br />    <img height="295" alt="1.3 C++ Object Model.JPG" src="http://www.cppblog.com/images/cppblog_com/jzp/Inside%20The%20C++%20Object%20Model/1.3%20C++%20Object%20Model.JPG" width="466" border="0" /> </p>
		<p>    d. 加上继承(Adding Inheritance)<br />    在 A Simple Object Model 中，每一个基类可以被derived class object的一个slot指出，该slot内含base class subobject的地址。<br />    在虚拟继承的情况下，base class 不管在继承链中被派生多少次，永远只有一个实体(subobject). 书中以iostream继承体系说明。</p>
		<p>    C++中的base class subobject的data members直接放置于derived class object中。那么它的function members是怎么处理的呢？(我没有理解这块)<br />    对于virtual base class, C++ 2.0 是在class object中添加一个关联 virtual base class object的指针。</p>
		<p>    e. 对象模型对程序的影响<br />    我觉得书上的这段代码非常好的体现了不同模型对程序的影响<br />    预定义 class X 如下：<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">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> X<br /><img id="Codehighlighter1_8_103_Open_Image" onclick="this.style.display='none'; Codehighlighter1_8_103_Open_Text.style.display='none'; Codehighlighter1_8_103_Closed_Image.style.display='inline'; Codehighlighter1_8_103_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_8_103_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_8_103_Closed_Text.style.display='none'; Codehighlighter1_8_103_Open_Image.style.display='inline'; Codehighlighter1_8_103_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_8_103_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_8_103_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img id="Codehighlighter1_34_40_Open_Image" onclick="this.style.display='none'; Codehighlighter1_34_40_Open_Text.style.display='none'; Codehighlighter1_34_40_Closed_Image.style.display='inline'; Codehighlighter1_34_40_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_34_40_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_34_40_Closed_Text.style.display='none'; Codehighlighter1_34_40_Open_Image.style.display='inline'; Codehighlighter1_34_40_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">~</span>
						<span style="COLOR: #000000">X()</span>
						<span id="Codehighlighter1_34_40_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_34_40_Open_Text">
								<span style="COLOR: #000000">{ <img src="http://www.cppblog.com/images/dot.gif" /> }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_64_70_Open_Image" onclick="this.style.display='none'; Codehighlighter1_64_70_Open_Text.style.display='none'; Codehighlighter1_64_70_Closed_Image.style.display='inline'; Codehighlighter1_64_70_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_64_70_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_64_70_Closed_Text.style.display='none'; Codehighlighter1_64_70_Open_Image.style.display='inline'; Codehighlighter1_64_70_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    X</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000"> X(</span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> X</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000"> rhs)</span>
						<span id="Codehighlighter1_64_70_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_64_70_Open_Text">
								<span style="COLOR: #000000">{ <img src="http://www.cppblog.com/images/dot.gif" /> }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								<br />
								<img id="Codehighlighter1_95_101_Open_Image" onclick="this.style.display='none'; Codehighlighter1_95_101_Open_Text.style.display='none'; Codehighlighter1_95_101_Closed_Image.style.display='inline'; Codehighlighter1_95_101_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_95_101_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_95_101_Closed_Text.style.display='none'; Codehighlighter1_95_101_Open_Image.style.display='inline'; Codehighlighter1_95_101_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> foo()</span>
						<span id="Codehighlighter1_95_101_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_95_101_Open_Text">
								<span style="COLOR: #000000">{ <img src="http://www.cppblog.com/images/dot.gif" /> }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 定义一个方法</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">X foobar()<br /><img id="Codehighlighter1_127_235_Open_Image" onclick="this.style.display='none'; Codehighlighter1_127_235_Open_Text.style.display='none'; Codehighlighter1_127_235_Closed_Image.style.display='inline'; Codehighlighter1_127_235_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_127_235_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_127_235_Closed_Text.style.display='none'; Codehighlighter1_127_235_Open_Image.style.display='inline'; Codehighlighter1_127_235_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_127_235_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_127_235_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    X xx;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    X </span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">px </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000"> X();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">    xx.foo();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    px</span>
						<span style="COLOR: #000000">-&gt;</span>
						<span style="COLOR: #000000">foo();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #000000">    delete px;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> xx;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 这个函数可能的转化为：</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> foobar(X</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000"> _result)<br /><img id="Codehighlighter1_277_554_Open_Image" onclick="this.style.display='none'; Codehighlighter1_277_554_Open_Text.style.display='none'; Codehighlighter1_277_554_Closed_Image.style.display='inline'; Codehighlighter1_277_554_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_277_554_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_277_554_Closed_Text.style.display='none'; Codehighlighter1_277_554_Open_Image.style.display='inline'; Codehighlighter1_277_554_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_277_554_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_277_554_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    _result.X::X();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #000000">    px </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">new</span>
						<span style="COLOR: #000000">( </span>
						<span style="COLOR: #0000ff">sizeof</span>
						<span style="COLOR: #000000">(X) );<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000">(px </span>
						<span style="COLOR: #000000">!=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        px</span>
						<span style="COLOR: #000000">-&gt;</span>
						<span style="COLOR: #000000">X::X();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 这里是不使用virtual 机制的foo调用<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 注意这里的调用方法，不是用vtbl, <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 这样如果有从class X 继承的类初始化或赋值给X基类时，<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 调用foo的方法是X的方法, 是编译时确定的</span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">    foo(</span>
						<span style="COLOR: #000000">&amp;</span>
						<span style="COLOR: #000000">_result);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 是用virtual 机制的foo调用, 它是运行时确定的<br /></span>
						<span style="COLOR: #008000">
								<img id="Codehighlighter1_2_169_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2_169_Open_Text.style.display='none'; Codehighlighter1_2_169_Closed_Image.style.display='inline'; Codehighlighter1_2_169_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_2_169_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2_169_Closed_Text.style.display='none'; Codehighlighter1_2_169_Open_Image.style.display='inline'; Codehighlighter1_2_169_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
								<span id="Codehighlighter1_2_169_Open_Text">
										<span style="COLOR: #000000"> (</span>
										<span style="COLOR: #000000">*</span>
										<span style="COLOR: #000000">px</span>
										<span style="COLOR: #000000">-&gt;</span>
										<span style="COLOR: #000000">vtbl[</span>
										<span style="COLOR: #000000">2</span>
										<span style="COLOR: #000000">])(px);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />     </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> delete px </span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
										</span>
										<span style="COLOR: #000000">     </span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(px </span>
										<span style="COLOR: #000000">!=</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #000000">0</span>
										<span style="COLOR: #000000">)<br /><img id="Codehighlighter1_70_143_Open_Image" onclick="this.style.display='none'; Codehighlighter1_70_143_Open_Text.style.display='none'; Codehighlighter1_70_143_Closed_Image.style.display='inline'; Codehighlighter1_70_143_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_70_143_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_70_143_Closed_Text.style.display='none'; Codehighlighter1_70_143_Open_Image.style.display='inline'; Codehighlighter1_70_143_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
										<span id="Codehighlighter1_70_143_Open_Text">
												<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />         (</span>
												<span style="COLOR: #000000">*</span>
												<span style="COLOR: #000000">px</span>
												<span style="COLOR: #000000">-&gt;</span>
												<span style="COLOR: #000000">vtbl[</span>
												<span style="COLOR: #000000">1</span>
												<span style="COLOR: #000000">])(px);  </span>
												<span style="COLOR: #008000">//</span>
												<span style="COLOR: #008000"> destructor</span>
												<span style="COLOR: #008000">
														<br />
														<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
												</span>
												<span style="COLOR: #000000">         _delete(px);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     }</span>
										</span>
										<span style="COLOR: #000000">
												<br />
												<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
												<br />
												<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />     </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> </span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
										</span>
										<span style="COLOR: #000000">     </span>
										<span style="COLOR: #0000ff">return</span>
										<span style="COLOR: #000000"> ;</span>
								</span>
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
				</span>
		</div>
		<p>
				<strong>
						<font size="4">
								<br />四. 关键词所带来的差异(A Keyword Distinction)</font>
				</strong>
				<br />    讨论了class 和 struct 的差异和选择<br /></p>
		<p>
				<strong>
						<font size="4">五. 对象的差异( A Object Distinction)<br /><br /></font>
				</strong>    <strong>1. C++程序设计模型支持三种programming paradigms.<br /></strong>    a. 程序模型(procedural model) 就是像 C 一样进行编程<br />    b. 抽象数据类型模型(abstract data type model, ADT) 用对象进行编程<br />    c. 面向对象模型(object-oriented model)<br />    模型中有一些彼此相关的类型，通过一个抽象的base class被封装起来(也就是：接口)。类型之间的操作是通过接口进行的。</p>
		<p>    纯粹的以一种paradigm写程序是好的.(哈哈，好像这不太可能，我还做不到)<br /></p>
		<p> <strong>  二. 面向对象模型(object-oriented model)</strong><br />    a . C++中多态支持性的支持是通过: pointer 和 reference来实现的. <br />    多态通过下面三种方法来支持:<br />        i. 经由一组隐含的转化操作:   shape *ps = new circle(); <br />        ii. 经由virtual function 机制  ps-&gt;rotate();<br />        iii. 经由 dynamic_cast和typeid来支持:<br />             if(circle *pc = dynamic_cast&lt;circle*&gt;(ps)) ...<br />   多态内存需求<br />       i. 其 nonstatic data members 的总和大小<br />       ii. 任何字节对齐的额外填充(padding)<br />       iii. 支持virtual 而产生的额外负担<br />    <br />    b. 指针的类型<br />    "指向不同类型的各指针"的差异，不在于其指针的表示法不同，也不在于其内容的不同， 而是其寻址出来的object的类型不同。也就是说"指针类型"会教导编译器如何解释某个特定地址中的内存内容及其大小.</p>
		<p>    c.  加上多态之后(Adding Polymorphism)<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: #008080"> 1</span>
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Bear : </span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> ZooAnimal<br /></span>
				<span style="COLOR: #008080"> 2</span>
				<span style="COLOR: #000000">
						<img id="Codehighlighter1_30_228_Open_Image" onclick="this.style.display='none'; Codehighlighter1_30_228_Open_Text.style.display='none'; Codehighlighter1_30_228_Closed_Image.style.display='inline'; Codehighlighter1_30_228_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_30_228_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_30_228_Closed_Text.style.display='none'; Codehighlighter1_30_228_Open_Image.style.display='inline'; Codehighlighter1_30_228_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span id="Codehighlighter1_30_228_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_30_228_Open_Text">
						<span style="COLOR: #000000">{ <br /></span>
						<span style="COLOR: #008080"> 3</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">: <br /></span>
						<span style="COLOR: #008080"> 4</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Bear(); <br /></span>
						<span style="COLOR: #008080"> 5</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #000000">~</span>
						<span style="COLOR: #000000">Bear(); <br /></span>
						<span style="COLOR: #008080"> 6</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								<br />
						</span>
						<span style="COLOR: #008080"> 7</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </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: #008080"> 8</span>
						<span style="COLOR: #008000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">    </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> rotate(); <br /></span>
						<span style="COLOR: #008080"> 9</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> dance(); <br /></span>
						<span style="COLOR: #008080">10</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								<br />
						</span>
						<span style="COLOR: #008080">11</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </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: #008080">12</span>
						<span style="COLOR: #008000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">protected</span>
						<span style="COLOR: #000000">: <br /></span>
						<span style="COLOR: #008080">13</span>
						<span style="COLOR: #000000">
								<img id="Codehighlighter1_170_176_Open_Image" onclick="this.style.display='none'; Codehighlighter1_170_176_Open_Text.style.display='none'; Codehighlighter1_170_176_Closed_Image.style.display='inline'; Codehighlighter1_170_176_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_170_176_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_170_176_Closed_Text.style.display='none'; Codehighlighter1_170_176_Open_Image.style.display='inline'; Codehighlighter1_170_176_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">enum</span>
						<span style="COLOR: #000000"> Dances </span>
						<span id="Codehighlighter1_170_176_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_170_176_Open_Text">
								<span style="COLOR: #000000">{ <img src="http://www.cppblog.com/images/dot.gif" /> }</span>
						</span>
						<span style="COLOR: #000000">; <br /></span>
						<span style="COLOR: #008080">14</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								<br />
						</span>
						<span style="COLOR: #008080">15</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Dances dances_known; <br /></span>
						<span style="COLOR: #008080">16</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> cell_block; <br /></span>
						<span style="COLOR: #008080">17</span>
						<span style="COLOR: #000000">
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">; <br /></span>
				<span style="COLOR: #008080">18</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
				</span>
				<span style="COLOR: #008080">19</span>
				<span style="COLOR: #000000">
						<img id="Codehighlighter1_233_236_Open_Image" onclick="this.style.display='none'; Codehighlighter1_233_236_Open_Text.style.display='none'; Codehighlighter1_233_236_Closed_Image.style.display='inline'; Codehighlighter1_233_236_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_233_236_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_233_236_Closed_Text.style.display='none'; Codehighlighter1_233_236_Open_Image.style.display='inline'; Codehighlighter1_233_236_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span id="Codehighlighter1_233_236_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
				<span id="Codehighlighter1_233_236_Open_Text">
						<span style="COLOR: #808080">///</span>
				</span>
				<br />
				<span style="COLOR: #008080">20</span>
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">Bear b( </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Yogi</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> ); <br /></span>
				<span style="COLOR: #008080">21</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />Bear </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">pb </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">b; <br /></span>
				<span style="COLOR: #008080">22</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />Bear </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">rb </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">pb; <br /></span>
				<span style="COLOR: #008080">23</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
		</div>
		<p>    具体的内存布局如 <br />    <br />    <img title="1.5 Layout of Object and Pointer of Derived Class" height="357" alt="1.5 Layout of Object and Pointer of Derived Class.JPG" src="http://www.cppblog.com/images/cppblog_com/jzp/Inside%20The%20C++%20Object%20Model/1.5%20Layout%20of%20Object%20and%20Pointer%20of%20Derived%20Class.JPG" width="405" border="0" /></p>
		<p>    // <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: #008080">1</span> <span style="COLOR: #000000">Bear b;<br /></span><span style="COLOR: #008080">2</span> <span style="COLOR: #000000">ZooAnimal </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pz </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">b;<br /></span><span style="COLOR: #008080">3</span> <span style="COLOR: #000000">Bear </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pb </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">b;<br /></span><span style="COLOR: #008080">4</span> <span style="COLOR: #000000"></span></div>
		<p>以上每个都指向Bear object的第一个byte，<font color="#ff0000" size="2"><strong>其间的差别是，pb所涵盖的地址包含整个的Bear object, 而pz所涵盖的地址只包含Bear object中的 ZooAnimal subobject部分</strong></font>。你只能用pz来处理Bear中的virtual functions, 而不能直接的处理Bear中的其他任何members.<br />    注意pz的类型将在编译时确定以下两点: <br />     i. pz固定的可用接口<br />     ii. pz的接口的access level；因为子类的access level可能是不同于基类的，编译时会检测是否可以转换。</p>
		<p>    e. 对象赋值问题<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">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000"> Bear b; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> ZooAnimal za </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> b; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> ZooAnimal::rotate() invoked </span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000"> za.rotate(); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p>
				<br />    这里有两个问题<br />    i. za为什么调用的是ZoomAnimal::rotate的实体而不是 Bear的实体?<br />   答：za并不是一个Bear, 它只是一个ZoomAnimal, 多态的这种特性不能用在直接存取的objects上。所以  za.rotate()调用只能是 ZooAnimal::rotate()</p>
		<p>    ii. 如果初始化函数将一个object的内容完全拷贝到另一个object中去，为什么za的vpt不是指向Bear的virtual table呢？<br />    答：编译器在初始化或赋值操作时，如果某个object含有一个或多个vptrs, 那么这些vptrs的内容不会被原对象初始化或改变.<br /> 例如上例的 ZooAnimal za = b, 这里的vptr并不会被 b 的vptr所替代.<br />    <br />    </p>
		<p>
				<br />    </p>
		<p>
				<br />    </p>
		<p> </p>
		<p> </p>
		<p> </p>
<img src ="http://www.cppblog.com/jzp/aggbug/5826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jzp/" target="_blank">猩猩</a> 2006-04-18 17:31 <a href="http://www.cppblog.com/jzp/articles/5826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>