??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品无码久久SM,91精品国产9l久久久久,久久九九免费高清视频http://www.shnenglu.com/jzp/category/1436.html ----- 要黑黑dzh-cnMon, 19 May 2008 17:10:44 GMTMon, 19 May 2008 17:10:44 GMT60Inside The C++ Object Model 学习W记--Semantics of Construction, Destructin, and Copyhttp://www.shnenglu.com/jzp/articles/14380.html猩猩猩猩Mon, 30 Oct 2006 06:42:00 GMThttp://www.shnenglu.com/jzp/articles/14380.htmlhttp://www.shnenglu.com/jzp/comments/14380.htmlhttp://www.shnenglu.com/jzp/articles/14380.html#Feedback0http://www.shnenglu.com/jzp/comments/commentRss/14380.htmlhttp://www.shnenglu.com/jzp/services/trackbacks/14380.htmlChapter 5. Semantics of Construction, Destruction, and Copy

5.1 “无l承?情况下的对象构?br />1. 普通类?和C相同)
2. 抽相数据cd
3. 为承作准备

5.2 l承体系下对象的构?br />1.  通用l承构造规?br />     (1) 在成员初始化列表中的data members初始化操作会被放qconstructor的函数本w,q以members的声明顺序ؓ序?br />     (2) 如果有一个member没有出现在初始化列表中,但它有一个default constructorQ那么default constructor会被调用?br />     (3) 如果class object 有virtual table pointer(s)Q???必须被设定初始|指向适当的virtual table(s)?br />     (4) 在那之前Q所有的上一层的base class constructors必须被调? 以base class的声明顺序ؓ序
     (5) 在那之前Q所有的virtual base class constructors必须被调用,从左到右Q从最深到最?

2. 虚拟l承(virtual Inheritance)
如对于下面的c? 

 1 class Point3d : public virtual Point
 2  { 
 3  public
 4     Point3d( float x = 0.0float y = 0.0float z = 0.0 ) 
 5         : Point( x, y ), _z( z ) {} 
 6     Point3d( const Point3d& rhs ) 
 7         : Point( rhs ), _z( rhs._z ) {} 
 8     ~Point3d(); 
 9     Point3d& operator=const Point3d& ); 
10 
11     virtual float z(){ return _z; } 
12     //  
13  protected
14     float _z; 
15  }; 

 
 可能的{换是q样?

 1 // Psuedo C++ Code: 
 2  // Constructor Augmentation with Virtual Base class 
 3  Point3d* Point3d::Point3d( Point3d *thisbool __most_derived,  float x, float y, float z ) 
 4  { 
 5   if ( __most_derived != false ) 
 6    this->Point::Point( x, y); 
 7 
 8   this->__vptr__Point3d = __vtbl__Point3d; 
 9   this->__vptr__Point3d__Point = __vtbl__Point3d__Point; 
10 
11   this->_z = rhs._z; 
12   return this
13  } 

 //
 对于如下的承层?
 class Vertex   : virtual public Point { ... };
 class Vertex3d : public Point3d, public Vertex { ... };
 class PVertex  : public Vertex3d { ... };

 cPoint3d的构造可能是:

 1 // Psuedo C++ Code: 
 2  // Constructor Augmentation with Virtual Base class 
 3  Point3d* Point3d::Point3d( Point3d *thisbool __most_derived,  float x, float y, float z ) 
 4  { 
 5   if ( __most_derived != false ) 
 6    this->Point::Point( x, y); 
 7 
 8   this->__vptr__Point3d = __vtbl__Point3d; 
 9   this->__vptr__Point3d__Point = __vtbl__Point3d__Point; 
10 
11    this->_z = rhs._z; 
12   return this
13  }

 //
 对于Vertex3d的构造可能是如下:

 1 // Psuedo C++ Code: 
 2  // Constructor Augmentation with Virtual Base class 
 3  Vertex3d* Vertex3d::Vertex3d( Vertex3d *thisbool __most_derived, float x, float y, float z ) 
 4  { 
 5   if ( __most_derived != false ) 
 6    this->Point::Point( x, y); 
 7 
 8   // invoke immediate base classes, 
 9   // setting __most_derived to false 
10 
11   this->Point3d::Point3d( false, x, y, z ); 
12   this->Vertex::Vertex( false, x, y ); 
13 
14   // set vptrs 
15   // insert user code 
16 
17   return this
18  } 

 

3. vptr初始化语意学(The Semantics of the vptr Initialization)
     (1) 构造函数执行算?br />          I.    在derived class constructor ? 所有的"virtual base classes" ?"上一层base class"的constructors会被调用.
   II.  上述完成之后, 对象的vptr(s)会被初始? 指向相关的virtual talbe(s).
   III. 如果有成员初始化列表的话, 在constructor体内扩展开? q必dvptr被设定之后才能进?以免有一个virtual member function被调?br />   IV. 最? 执行E序所提供的代?
    
     (2) CZ:
     For example, given the following user-defined PVertex constructor:

1 PVertex::PVertex( float x, float y, float z ) 
2     : _next( 0 ), Vertex3d( x, y, z )
3     , Point( x, y ) 
4  { 
5   if ( spyOn ) 
6    cerr << "within Point3d::Point3d()"  << " size: " << size() << endl; 
7  } 

 

  可能一个扩展如?

 1 // Pseudo C++ Code 
 2  // expansion of PVertex constructor 
 3  PVertex* PVertex::PVertex( Pvertex* this,  bool __most_derived, float x, float y, float z ) 
 4  { 
 5   // conditionally invoke the virtual base constructor 
 6   if ( __most_derived != false ) 
 7    this->Point::Point( x, y ); 
 8   // unconditional invocation of immediate base 
 9    this->Vertex3d::Vertex3d( x, y, z ); 
10 
11   // initialize associated vptrs 
12 
13   this->__vptr__PVertex = __vtbl__PVertex; 
14   this->__vptr__Point__PVertex = __vtbl__Point__PVertex; 
15 
16   // explicit user code 
17   if ( spyOn ) 
18    cerr << "within Point3d::Point3d()" 
19    << " size: " << (*this->__vptr__PVertex[ 3 ].faddr)(this
20    << endl; 
21 
22   // return constructed object 
23   return this
24  } 

 


5.3 对象的复?Object Copy Sematics)
1. Copy constructor operator 在以下几U情况下不会表现? bitwisecopy
     (1) class 内带有一个member object, 而其cL一个copy constructor operator时?br />     (2)  当一?class 的base 有一个copy assignment operator时?br />     (3)  当类声明了Q何一个virtual functions时?br />     (4)  当classl承自一个virtual base class?br /> 2. 合成CZ

 1  // Pseudo C++ Code: synthesized copy assignment operator 
 2  inline Point3d& Point3d::operator=( Point3d *const thisconst Point3d &p ) 
 3  { 
 4   // invoke the base class instance 
 5   this->Point::operator=( p ); 
 6 
 7   // memberwise copy the derived class members 
 8   _z = p._z; 
 9   return *this
10  } 

 

5.4 对象的功?/p>


5.5 析构语意?Semantics of Destruction)
1. 析构函数生成原则Q?br /> 如果cL有定义destructor, 那么只有在class内带的member object(或是class自己的base class)拥有destructor的情况下Q编译器才会自动的合成一个来。否则,destructor会被视ؓ不需要,也就不需要被合成(当然更不需要被调用)

2. 析构调用q程
     (1) destructor的函数本w首先被执行?br />     (2) 如果class拥有member class objects, 而后者拥有destructors, 那么它会以其声明序的相反顺序被调用.
     (3) 如果object内带一个vptrQ?则现在被重新讑֮Q指向适当的base class的virtual table.
     (4) 如果M直接?上一?novirtual base classes 拥有destructorQ那么它会以其声明顺序相反的序调用
     (5) 如果有Q何的virtual base classes 拥有destructorQ?而当前讨论的q个class是最末端的classQ?那么它们会以其原来的构造顺序相反的序被调?

 



猩猩 2006-10-30 14:42 发表评论
]]>
Inside The C++ Object Model 学习W记--The Semantics of Functionhttp://www.shnenglu.com/jzp/articles/14379.html猩猩猩猩Mon, 30 Oct 2006 06:39:00 GMThttp://www.shnenglu.com/jzp/articles/14379.htmlhttp://www.shnenglu.com/jzp/comments/14379.htmlhttp://www.shnenglu.com/jzp/articles/14379.html#Feedback0http://www.shnenglu.com/jzp/comments/commentRss/14379.htmlhttp://www.shnenglu.com/jzp/services/trackbacks/14379.htmlChapter 4.  The Semantics of Function: Function 语意?/p>

4.1 Member 函数的各U调用方?br />1. Nonstatic Member Function(非静态成员函?
    要做如下的{?
    (1) 改写函数的原? 安插一个参数到member function? 用于提供一个存取管? 使class object 得以调用该函? q个额外的指针称之ؓ: this指针.
    ?  
 Point3d::magnitude()  会{换ؓ:  Point3d::magnitude(Point3d *const  this)

    (2)  对函数内每一个针对nostatic data member的存取操作改l由this指针来存?
     ?
           return sqrt(
  this->_x  *  this->_x  + this->y * this->_y  + this->_z * this->_z;
    (3)  对member function 重写一个外部函? 对函数名U进?mangling"处理, 使它生成一个独一无二的名U?br />   
2. Virtual Member Function(虚拟成员函数)
     例如:
  ptr->normalize();
  它将被{化ؓ如下的调?
 ( * ptr->vptr[ 1 ])( ptr );
 q里有几点说明: 
 i.  vptr是由~译器生成的指针Q指向virtual table
 ii.  1 q里是virtual table slot 的烦引|它关联到nomalizeq个函数
 iii.  W二个ptr表示this指针

3. Static Member Function(静态成员函?
     如果Point3d::normalize()是一个static member function的话Q这两个调用会{化ؓ一般的操作Q?br />     obj.normalize();
     ptr->normalize();
     转化为: 
     // obj.normalize();
     normalize__7Point3dSFv();
     // ptr->normalize();
     normalize__7Point3dSfv();

4.2 Virtual Member Functions(虚拟成员函数)
1. 单一l承下的Virtual Functions
     一个多态的class object w上增加两个members:
 I.   一个字W串或数?  表示class的类?br /> II.  一个指针,指向某个表格Q表g带有E序的virtual function的执行时期地址
    对于一个active virtual function包括下面三个内容Q 
        I.   q个class 所定义的函数实? 它会改写一个可能存在的base class virtual function 函数实体.
 II.  l承自基cȝ实体Q q是在derived class 军_不改写virtual function 时才会出现的情况
 III. 一个pure_virtual_called()函数实体Q它既可以扮演pur virtual function的空间保卫者角? 也可以当做执行期异常函数.

2. 多重l承下的Virtual Functions
    q种l承涉及到要调整this指针Qƈ且要求不止一个vtbl和vptrQ同时要好几个这U虚表和指针

3. 虚拟l承下的Virtual Functions


4.3 函数的效?/p>

4.4 指向Member Functions的指?Pointer-to-Member Functions)
1. 指向一般成员函数的指针(Nostatic member and novirtual member function)
    取一个nostatic member function的地址,  如果该函数是novirtual, 则得到的l果是它在内存中真正的地址, 然而这个地址也不是完全的, 它也需要绑定到某个class object的地址? 才能够调用该函数. 所有的nostatic member functions都要对象的地址(用this指出).
    例如:
     double (Point::*pmf)(); // 定义一个成员函数指?br />      pfm = &Point::y;   // 初始化这个指针ؓ
     (ptr->*pfm)() ;   // 调用?  ~译器{化ؓ: (pfm)(ptr)

2. 支持"指向Virtual Member Functions"的指?br />    对于virtual function, 其地址在编译时期是未知? 所能知道的仅是virtual function在相关的vitual table 中的索引? 也就是说对于一个virtual member function取其地址, 所能获得的只是一个烦引?
    所以如?
    pmf = &Point::z(); // 获得的是索引?  调用?
    (ptr.->pmf)()   // 会{化ؓ: (* ptr->vptr[(int)pfm] (ptr)

3. 在多重承下,指向Member Functions的指?br />     比较复杂,  定义了一个结构支持这们的操作

4. 指向 Member Functions 指针的效?/p>


4.4 Inline Functions
1. inline functions的生成条?/p>

2. 对Ş式参数的处理(Formal Arguments)
例如:

 1 inline int min( int i, int j ) 
 2  { 
 3     return i < j ? i : j; 
 4  } 
 5  and the following three invocations of the inline function:
 6 
 7  inline int bar() 
 8  { 
 9     int minval; 
10     int val1 = 1024
11     int val2 = 2048
12 
13  /*(1)*/minval = min( val1, val2 ); 
14  /*(2)*/minval = min( 10242048 ); 
15  /*(3)*/minval = min( foo(), bar()+1 ); 
16 
17     return minval; 
18  } 

 
用下面的方式q行处理:
   (1)  直接的参数替?br /> //(1)     simple argument substitution
 minval = val1 < val2 ? val1 : val2;

   (2) 如果实际参数是一个常量表辑ּ(const expression),  我们可以在替换前完成对它的求值操?
 //(2)  constant folding following substitution
 minval = 1024;
  
   (3) 带有副作用的实际参数, 引入临时性的对象
 //(3)     side-effects and introduction of temporary
 int t1;
 int t2;

 minval =  ( t1 = foo() ), ( t2 = bar() + 1 ),  t1 < t2 ? t1 : t2;

3. 对inline函数带有局部变量的处理(Local Variables)
    ?
 inline int min( int i, int j )
 {
  int minval = i < j ? i : j;
  return minval;
 }
    对于如下的调?
    {
    int local_var;
    int minval;

    // ...
    minval = min( val1, val2 );
     }

    转换可能的结果是:

1     { 
2     int local_var; 
3     int minval; 
4     // mangled inline local variable 
5     int __min_lv_minval; 
6 
7     minval =  ( __min_lv_minval =  val1 < val2 ? val1 : val2 ),  __min_lv_minval; 
8      }

 



猩猩 2006-10-30 14:39 发表评论
]]>
Inside The C++ Object Model 学习W记--The Semantics of Datahttp://www.shnenglu.com/jzp/articles/14378.html猩猩猩猩Mon, 30 Oct 2006 06:36:00 GMThttp://www.shnenglu.com/jzp/articles/14378.htmlhttp://www.shnenglu.com/jzp/comments/14378.htmlhttp://www.shnenglu.com/jzp/articles/14378.html#Feedback0http://www.shnenglu.com/jzp/comments/commentRss/14378.htmlhttp://www.shnenglu.com/jzp/services/trackbacks/14378.htmlChapter 3. The Semantics of Data : Data 语义?/p>

CZ代码Q?br />class X {};
class Y : public virtual X {};
class Z : public virtual X {};
class A : public Y, public Z {};


一个类对象的大受三个因素的媄?br />i.   语言本n所造成的额外负?overhead),  当语a要支持virtual base class Ӟ׃D一些额外的负担.
ii.  ~译器对Ҏ情况所提供的优化处?  如virtual base class class X subobject ?bytes大小会出现在子类Y, Z的n?
      ? sizeof(Y) = sizeof(Z) = 4(8) // q里?(8)和编译器相关
     
      有时候有的编译器会用empty virtual base class 技术来优化, VC是采用q一技术的, q样virtual base class ׃用占用大了.

iii.  Alignment 的限? Y和Z的大本来大都?, 加上virtual base subobject?bytes的大共5个字? 但实际上L8bytesQ这里就是受到字节对齐的影响.

C++对象模型Ҏ据的存放l构?
i.   把nonstatic data members直接的放在class object之中, 对?不管是virtual ?nonvirtual base class )而来的nonstatic data members也是q一L.
ii.  没有强制定义光的排列顺?br />iii. 对static data members, 则被攄在一个global data segment? 不会影响单个cȝ大小, q且只保存一份实? (template有所不同)

3.1 Data Member的绑?The Binding of Data Member)
    CZ代码:

 1 // A third party foo.h header file 
 2  // pulled in from somewhere 
 3  extern float x; 
 4 
 5  // the programmer's Point3d.h file 
 6  class Point3d 
 7  { 
 8  public
 9     Point3d( floatfloatfloat ); 
10 
11     // question:  which x is returned and set? 
12     float X() const { return x; } 
13 
14     void X( float new_x ) const { x = new_x; } 
15 
16     //  
17 
18  private
19     float x, y, z; 
20  }; 
21 
22 


 在早期的~译器中会出? 不过?C++2.0后就不会? 在C++2.0? 采用的是"rewriting rule" == "member scope rsolution rule" 规则来处理它.
 以前的编译器? float X() const { return x; }, 它不知道要返回哪一个x, q里它会q回全局?extern float x, 所以是不正的. 后来的编译器是会在整个class的声明都出现了后才会分析member functions, 所以它不会现错.

 对于下面的例子还是会出错, 因ؓ对于member functions signatures的分析不会到cd成以? 而是W一ơ出现的时候就会分析的. 如下面的:

  所以最好始l的?nested type declare" 攑֜cȝ起始? (q在STL中好像最明显, 都是先声明的)


3.2 Data Member的布局 (Data Member Layout)

CZ代码: 

 1 class Point3d { 
 2  public
 3 
 4     //  
 5 
 6  private
 7     float x; 
 8     static List<Point3d*> *freeList; 
 9     float y; 
10     static const int chunkSize = 250
11     float z; 
12  }; 
13 

      Data Member的布局按如下的规则:
      i.   Nonstatic data member 在class object中的排列序和被声明的顺序是一L, M中间介入的static data member都不会被放进对象的布局?
      ii.  要求在同一access section?较晚出现的members在class object中有较高的地址"q一条g可?
      iii. ~译器可能会合成一些内部用的data members, 以支持整个对象模? 如vptr指针.  对于它的具体位置, C++ Standard 没有规定, q译器产商自己军_. 不过传统上一般是攑֜所有声明的members的最? 也有把vptr攑֜所有class object的最前端?


3.3 Data Member的存?br />CZ:
      Point3d origin, *pt = &origin;
      origin.x    = 0.0;
      pt->x = 0.0

1. Static Data Members的存?br />    每一个static data member只有一个实体,存在于程序的data segment中。每ơ程序取用这个static data member的时候,׃被{化ؓ对该实体的唯一的extern实体的直接参考操?  用指针存取一个数和用对象d取一个数是一L?br />    
2. Nostatic Data Members的存?br />    Nostatic data member 直接存放在每一个class object之中Q除非经由明的或暗ȝclass objectQ否则没有办法直接的存取它们?br />    例如:
    Point3d  Point3d::translate( const Point3d &pt )
    {
    x += pt.x;
    y += pt.y;
    z += pt.z;
    }
    实际l过转换后ؓQ?br />    Point3d  Point3d::translate( Point3d *const this, const Point3d &pt )
    {
     this->x += pt.x;
    this->y += pt.y;
    this->z += pt.z;
    }
    对nostatic data member的访问是q样? 
 origin._y = 0.0; 
    实际转换操作?
        &origin + (&Point3d::_y - 1 );
      
       注意:  q里?1操作。指向data member的指针,其offset值L被加?Q?q样可以使编译系l区分出:
 i.  一个用以指出class的第一个member的data member的指?
 ii. 一个没有指ZQ何member的data member的指?
  
    如果是virtual l承的话Q就可以不一样了Q可能要多加层的讉K? 也可能要到运行时才能军_Q由~译器所军_.


3.4 “扎쀝与Data Member
 CZ数据:

 1  // supporting abstract data types 
 2  class Point2d
 3  { 
 4  public
 5   // constructor(s) 
 6   // operations 
 7   // access functions 
 8  private
 9   float x, y; 
10  }; 
11 
12  /// 
13  class Point3d
14  { 
15  public
16   // constructor(s) 
17   // operations 
18   // access functions 
19  private
20   float x, y, z; 
21  }; 
22 

    C++的承模?
 在C++的承模型中Q?一个derived class object 所表现出来的东西,是其自己的member加上其base class(es) member的d。对于数据成员出现的序在C++ Standard 中没有规定。从下面几个斚w来讨论数据?
 i.   单一l承且不含有virtual functions
 ii.   单一l承q含有virtual functions
 iii.  多重l承
 iV. 虚拟l承

1. 只要l承不要多?Inheritance Without Polymoophism)
    l承一般不会增加空间或存取旉。但l承有时会有q样两种情况出现:
    i.   l验不的h有时可能会重复的设计一些相同的函数.
    ii.  把一个类分解为多层,有可能会Z表现class的体pL象化Q所需要的I间膨胀?br />        因ؓC++语言要保? 出现在derived class 中的base class subobject 有其完整原样性?/p>

2. 加上多?Adding Polymorphism)
    如:

 1  class Point2d 
 2  { 
 3  public
 4     Point2d( float x = 0.0float y = 0.0 ) 
 5        : _x( x ), _y( y ) {}; 
 6 
 7     // access functions for x & y same as above 
 8     // invariant across type: not made virtual 
 9   
10     // add placeholders for z ?do nothing  
11     virtual float z(){ return 0.0 }; 
12     virtual void z( float ) {} 
13 
14     // turn type explicit operations virtual 
15     virtual void operator+=const Point2d& rhs )
16     { 
17         _x += rhs.x(); _y += rhs.y();
18      } 
19   
20     //  more members 
21 
22  protected
23   float _x, _y; 
24  }; 
25 
26 


 //
 要支持多态,Point2d数据成员要做如下的工?
 i.   导入一个和Point2d有关的virtual table(vtbl), 存放它声明的每一个virtual function的地址
 ii.   在每个class object中导入一个vptr, 提供执行期的链接Q每个object都能扑ֈ相应的virtual table.
 iii.  加强construtor, 使它能够为vptr讑֮初|让它指向class所对应的virtual table.
 iV.  加强destructor, 使它能够Ҏ"指向class的相?virtual table" 的vptr.

 Figure 3.3. Data Layout: Single Inheritance with Virtual Inheritance
 

3. 多重l承(Multiple Inheritance)
 
 
4. 虚拟l承(Virtual Inheritance)
    Class 中如果含一个或多个virtual base class subobjects, 它将被分Z个部? 一个不变的局部和一个共享的局?
    i.   不变的局部中的数据,不管后如何衍化QL固定的offsetQ?所q一部分的数据可以直接的被存取?
    ii.  ׃n的局部,所表现的就是virtual base class subobject, q一部分的数据会因ؓ每次z的操作而有变化, 所以它们只能间接的存取?/p>


3.5 对象成员的效?Object Member Efficiency)

3.6 指向数据成员的指?Point to Data Members)



猩猩 2006-10-30 14:36 发表评论
]]>
Inside The C++ Object Model 学习W记 -- The Semantics Of Constructorshttp://www.shnenglu.com/jzp/articles/14377.html猩猩猩猩Mon, 30 Oct 2006 06:33:00 GMThttp://www.shnenglu.com/jzp/articles/14377.htmlhttp://www.shnenglu.com/jzp/comments/14377.htmlhttp://www.shnenglu.com/jzp/articles/14377.html#Feedback0http://www.shnenglu.com/jzp/comments/commentRss/14377.htmlhttp://www.shnenglu.com/jzp/services/trackbacks/14377.html2.1 Default Constructor 的构造操?br />    按照C++ Annotated Reference Manaual 的说法:"Default constructor... 在需要的时候被~译器生出?. q里的关键字是:“在需要的时候”?
    C++ Standard[ISO-C++95]中又有如下的声明Q对于class X, 如果没有Muser-declared constructorQ那么会有一个default constructor 被暗中声明出?...一个被暗中声明出来的default constructor 是一个trival的constructor"?q里我觉得主要是“user-declared constructor”,它包括用h定义的所有的constructorq有其它的一些有virtual关键字的操作。这样下面的四种情况下由~译器生成的constructor是notrival default constructorQ?br />   
    1. 带有 Default Constructor ?Member Class Object(带有~省构造函数的cL员对?
    如果一个类的带有一个或多个的类成员对象Q而类成员对象又有构造函敎ͼ那么׃生成该类׃生成一个notrival default constructor 构造函数?成员对象的构造函数的调用是按成员对象的声明顺序执行的。例如:

class  Foo  public : Foo(), Foo( int ) . } ;
class  Bar  public : Foo foo;  char   * str; }
  
void  foo_bar()
{
       Bar bar; 
//  Bar::foo在这里被初始?调用Foo的缺省构造行? Foo:Foo())
      
      
//
      if  (str)  { }   . 
   }

    
    对于有多个成员对象的c,则按成员对象在类的声明中的顺序调用它们的构造函数?br />      
    2. 带有 Default Constructor ?Base Class(带有~省构造函数的基类对象)       指的是一个没有Q何constructorsrs的类z自一个带有“default constructor”的基类?如果cd在多个构造函数的话,那么~译器也会扩充现有的每一个构造函敎ͼ调用基cȝdefault constructor的代码加入到其中?
       
    3. 带有一?Virtual Function ?Class
    q样的virtual Function可以使承来的或直接定义的?~译器在~译期间会做如下工作
    a. 生成一个virtual Function talbe(vtbl), 用来存放class 的virtual function的地址
    b. 在每一个class object中,d一个额外的pointer member(vptr)Q它指向class vtbl的地址
   
    4. 带有一?Virtual Base Class ?Class
    q种情况是在导出cȝ安插一个virtual base classes的指针,用来在运行时存取virtual base class 的成员。例如:

 1     class X { publicint i; }; 
 2     class A : public virtual X   { publicint j; }; 
 3     class B : public virtual X   { publicdouble d; }; 
 4     class C : public A, public B { publicint k; }; 
 5 
 6     // cannot resolve location of pa->X::i at compile-time 
 7     void foo( const A* pa ) { pa->= 1024; } 
 8     // 在编译期可能生成如下形式:
 9     // void foo(const A* pa) { pa->_vbcX->i = 1024; } // _vbcX: virtual base class X
10     
11     main() 
12     { 
13         foo( new A ); 
14         foo( new C ); 
15     
16         //  
17     }
18 
19 

    
    注意: 在合成的default constructor中,只有base class subobjects和member class objects会被初始化,其它所有的nostatic data member都不会执行初始化的操作.要我们自己手动的L行初始化的操作.

    其实把握一个原则:要不要合成一个构造函敎ͼ依据~译器的需要与否,合成出来的constructor也只是完成那些编译器所需求?br />   
    两个错误的观点:
 i. M时候,如果没有定义default constructorQ就会被合成一个出来?而是Ҏ~译器的需要决定是否生成一个deault constructor)
 ii. ~译器生成出来的default constructor会明的初始化每cM的每一个data member.


2.2 Copy Constructor的构建操?br />    有三U情况下会有一个Copy Constructor的操作:
 i.   对一个object做明的初始化操作 ?/ class X{ ....};   X x;    X xx = x;
 ii.  当某个object作ؓ参数传递给某个函数  // void foo(X x) { .... }
 iii. 函数传回一个class object对象  // void foo(){ X xx; return xx;}

    1. Default Memberwise Initialization(~省的按成员初始?
    如果一个类没有explicit copy constructor? class object在执行copy constructorӞ内部以default member initialization的手法来完成Q就是把每一个内建或者派生而来的data member的g某个object 拯一份到另一个objectw上Q对member class object是以递归的方式调用memberwise initialization的?br />   
    q种初始化是通过在必要时生成一个copy constructor或通过 bitwise copy 来完成的?如果要通过bitwise来完成这q样的操作,那么必须表现出bitwise copy semantise. 
   
    C++ Standard中也把copy constructor分成trial 和notrivial两种cdQ只有notrivial的实体才会被合成于程序中。决定一个copy constructor是否为trivial在于cL否表现出所谓的"Bitwise copy sematics".
   
    2. Bitwise Copy Semantics
    ?bitwise copy sematics 下,不会构造出一个default copy constructor. 例如Q?br /> 

 1    class Word
 2     {
 3     public
 4         Word(const char*);
 5         ~Word(){ delete []str; }
 6         //
 7     private:
 8         int cnt;
 9         char *str;
10     }  
11     以上的是一个表现出Bitwise copy sematics的类Q而以下是一个没有表现出bitwise copy sematics的类
12     class Word
13     {
14     public
15         Word(const char*);
16         ~Word(){ delete []str; }
17         //
18     private:
19         int cnt;
20         String str;
21     }
22     
23     class String 
24     {
25     public
26         String(const char*);
27         String(const string&); // String的显Ccopy constructor
28         ~String();
29         //.
30     }
31     q种情况下会合成一个copy constructor以调用class String object的copy constructor.
32     inline Word::Word(const Word& wd)
33     {
34         str.String::String(wd.str);
35         cnt = wd.cnt;
36     }    
37 

       
    3. 不表现出Bitwise Copy Sematics的特性的情况
    以下的几U情况class不表现出 Bitwise Sematics:
        a. 当class 内含有一个member object, 而后者的class 声明有一个copy constructor?合成或声明的都可?Q就不表现出Bitwise Sematics
        b. 当class l承自一个base class, 而后者存在有一个copy constructor(合成或声明的都可?, ׃表现出Bitwise Sematics.
        c. 当类声明了一个或多个virtual function?br />        d. 当classz自一个承创串链Q其中有一个或多个virtual base classes? cd不表现出Bitwise Sematics
    q四U情况和default constructor生成的是否一个trivial是一L, 也是满~译器的需求?br />      
    4. 重新讑֮Virtual Table 的指?br />    对于以上Q当cd明了一个或多个virtual function的情况,E序会ؓcd象做如下两个扩张操作Q?br />        (1) 增加一个vtbl的指针,内含virtual function的指针地址?br />        (2) 在类对象内安插一个vptr指针Q指向virtual function table.
    对于把一个base class object 以其derived class object的值初始化操作的时候,会发生切?sliced)操作。这时也要保证vtbl的正和vtpr的正性?br />   
    5. 处理Virtual Base Class Subobject
    如果一个class object是以另外一个object作ؓ初始值的话,而后者又有一个virtual base class suboject的话Q那么也会bitwise copy sematics失效。例如:

 1     class Raccoon : public virtual ZooAnimal{
 2     public:
 3   Raccoon(){  ; }
 4   Raccoon(int val) { ; }
 5   private:
 6   // 
 7     };
 8 
 9     class RedPanda : public Raccoon{
10     public:
11   RedPanda() { .; }
12   RedPanda(int val) { .; }
13   private:
14   // 
15     };
16     执行如下操作时会要求合成一个copy constructor:
17     RedPanda little_red;
18     Raccoon little_critter = little_re;  // q里~译器必L的把little_critter的virtual base class pointer/offset初始化?br />19 
20     // 如果只是q样的操作用bitwise copy 可以了
21     Raccoon rocky;
22     Raccoon little_critter = rocky;   // 用简单的bitwise copy 可以搞定了
23 
24 


2.3 E序转化语义?Program Transformation Semantics)
 指的是程序在执行的是候要做的cd和操作的转换?下面例子反映了三U{换操作:

 

 1  #include "X.h"
 2 
 3  X foo( X x0)
 4  {
 5   X xx;
 6 
 7   // ., 对xx和x0q行操作
 8 
 9   return XX;
10  }
11 

 

 1. 明确的初始化操作(Explicit Initialization)
 例如Q?br />

1 X x0
2   void  foo_bar()
3   {
4   X x1(x0);
5   X x2  =  x0;
6   X x3  =  X(x0);
7  }

8

 
 对程序做两个阶段的{化:
 i. 重写每一个定义,其中的初始化操作都会被剥?br /> ii. cȝCopy constructor操作会被安插q去
 转化后可能成L(伪码)Q?br /> q也是说前面三U的初始化操作都会{换成Explicit Initialization.

 1  void foo_bar()
 2  {
 3   X x1; 
 4   X x2;
 5   X x3;
 6 
 7   x1.X::X(x0);
 8   x2.X::X(x0);
 9   x3.X::X(x0);
10  }
11 
12 

 2. 参数的初始化(Argument Initialization)
 例如下面Q?br />

 1  void foo(X x0){ ; }
 2  void call()
 3  {
 4   X xx;
 5 
 6   // . xxx 初始化及其操?/span>
 7 
 8   foo(xx);
 9  }
10  转换后的操作为:
11  void call()
12  {
13   X xx;
14 
15   X __temp0;
16   __temp0.X::X(xx);
17   foo(__temp0);                // foo 函数应变成:void foo(X& x0);
18   __temp0.X::~X();  
19  }
20 
21 

 q就是ؓ什么当传值到孙数的时候,不会把函数内对传入值的操作l果不会被修改,因ؓ它在函数内本来修改的׃是外部传人的那个变量?/p>


 3. q回值的初始?Return Value Initialization)
 例如Q?
 X bar()
 {
  X xx;
  // ....
  return xx;
 } 
 
 转化为如下伪?
 void bar(X& __result)
 {
  X xx;
  xx.X::X();   // ~译器生成的一个缺省的构造函数调?/p>

  // 处理 ....

  __result.X::X(xx);    // ~译器生成的copy constructor调用操作
  return;
 }
 
 如下的操作{化ؓQ?br /> void foo()
 {
  X xx = bar();
 }

 被{化ؓQ?br /> void foo()
 {
  X xx;
  bar(xx);   // 注意q里不用执行 default constructor
 }
 
 针对q种转换Q可以从使用层面上进行优化和在编译器层面上做优化操作。在~译器层面上的操作就是采用NRV(Named Return Value)技术?br /> 如:
 x bar()
 {
  X xx;
  // ....
  return xx;
 }
 优化为:
 void bar(X& __result)
 {
  __result.X::X();

  //....  直接的处?__result

  //
  return ;
 } 

2.4 成员初始化队?Member Initialization List)
 q里有两点要注意Q?br /> 1. 以下的四U情况下必须使用 member intialization list
  I.   当初始化一个reference member?br />  II.  当初始化一个const member?br />  III. 当初始化一个base class 的constructorQ而它拥有一l参数时
  IV.  当调用一个member class的constructor, 而它拥有一l参数时

  其它情况下可以用在构造函数内初始化也可以
 
 2. 关于初始化的ơ序问题Q?br />  ~译器的初始化的序是按member声明ơ序来依ơ的初始化的。它会安插一些代码到构造函数内Qƈ攑֜M其它用户初始化的代码之前.

 



猩猩 2006-10-30 14:33 发表评论
]]>
Inside The C++ Object Model 学习W记 -- 关于对象http://www.shnenglu.com/jzp/articles/5826.html猩猩猩猩Tue, 18 Apr 2006 09:31:00 GMThttp://www.shnenglu.com/jzp/articles/5826.htmlhttp://www.shnenglu.com/jzp/comments/5826.htmlhttp://www.shnenglu.com/jzp/articles/5826.html#Feedback1http://www.shnenglu.com/jzp/comments/commentRss/5826.htmlhttp://www.shnenglu.com/jzp/services/trackbacks/5826.html 一. C/C++ 语言中的Ҏ和数?/strong>

    1. C语言的数据和Ҏ     语言中数据和处理(函数)是分开的,语言本n不支持数据和函数的关联性。这U方法我们称之ؓQ程序性的Q它是由"分布在各个以功能为导向的函数?d的算法所驱动Q它们处理的是共同的数据?/p>

     2. C++语言数据和方?/strong>
     C++中是通过ADT(Abstract Data Type, ADT)来实现的?C++可以在不同层ơ上q行抽象Q造成的复杂度可能也不一栗?br />     书中从简单到复杂四个层次的抽? 单类、ѝ一个参数的Template、两个参数的模板?br />


?C++加上装后的布局成本(Layout Costs for Adding Encapsulation)

    1. C++中的对象的布局
    a. data member:  直接的包涵在每一个class object(注意: cd象,不是c?之中Q这和C struct的情冉|一L
    b. member function: 它不出现在class object 之中.
       non-inline member: 它会产生一个行数的实体. 如果是非static的funciton, 每个function会加上一个this指针作ؓfunction的第一个参?
       inline member: 会在每一个用者n上生一个函数的实体。这一般是Z提高效率?br />   
    2. C++布局和存取上的额外开销
    a. virtual function 机制: 用以支持一个有效的"执行期绑?runtime binding)" 
    b. virtual base class


? C++对象模型(The C++ Object Model)

    1. 单对象模?A Simple Object Model)
    q种模型中,每个object是一pd的slots, 每个slot指向一个member. 每个member按其x的次序各占用一个slot. q里的member包括data member ?function member. 每个member是通过slot的烦引来讉K的?br />    具体的模型参? 
    1.1 Simple Object Model.JPG

    2. 表格驱动模型(A Table-driven Object Model)
    q种模型中把class object的members分组攑֜一个data member table 和一个function member table中,class object内含两个指向table的指? member function table 是一pd的slots, 每个slot指向一个function member. data member table 则是直接的包涉|data本n?br />    具体的模型参? 
    1.2 Member Table Object Model.JPG

    3. C++对象模型(The C++ Object Model)
    C++的对象模型如?
    a. nostatic data members 被直接的配置在每一个class object之内?br />    b. static data member 、static ?nonstatic function members全部被放在所有的class object 之外?br />    c. virtual functions 则是以下列步骤支持的Q?
        i. 每一个class 产生一堆指向virtual functions的指针,攑֜表格之中Q我们称q个表格为:virtual table(vtbl).
 ii. 每个得class object 被添加了一个指针,指向相关的virtual tableQ我们把class object的这个指针称之ؓvptr(virtual pointer)Q这个vptr的设定和重置是由cȝconstructor、destructor ?copy assignment q算W自动完成的Q每个类的type_info object也是l由virtual table指出的,通常是放在表格的W一个slot处?br />    具体的模型参? 
    1.3 C++ Object Model.JPG 

    d. 加上l承(Adding Inheritance)
    ?A Simple Object Model 中,每一个基cd以被derived class object的一个slot指出Q该slot内含base class subobject的地址?br />    在虚拟承的情况下,base class 不管在扉K中被z多少ơ,永远只有一个实?subobject). 书中以iostreaml承体系说明?/p>

    C++中的base class subobject的data members直接攄于derived class object中。那么它的function members是怎么处理的呢Q?我没有理解这?
    对于virtual base class, C++ 2.0 是在class object中添加一个关?virtual base class object的指针?/p>

    e. 对象模型对程序的影响
    我觉得书上的q段代码非常好的体现了不同模型对E序的媄?br />    预定?class X 如下Q?br />   

class  X
{
public :
    
virtual   ~ X()  }
    X
&  X( const  X &  rhs)  }

    
virtual   void  foo()  }
}


//  定义一个方?/span>
X foobar()
{
    X xx;
    X 
* px  =   new  X();
    
//  
    xx.foo();
    px
-> foo();

    
//
    delete px;
    
return  xx;
}


//  q个函数可能的{化ؓQ?/span>
void  foobar(X &  _result)
{
    _result.X::X();
 
    
//
    px  =   new sizeof (X) );
    
if (px  !=   0 )
        px
-> X::X();

    
//  q里是不使用virtual 机制的foo调用
    
//  注意q里的调用方法,不是用vtbl, 
    
//  q样如果有从class X l承的类初始化或赋值给X基类Ӟ
    
//  调用foo的方法是X的方? 是编译时定?/span>
    foo( & _result);

    
//  是用virtual 机制的foo调用, 它是q行时确定的
 ( * px -> vtbl[ 2 ])(px);

     
//  delete px 
      if (px  !=   0 )
 
{
         (
* px -> vtbl[ 1 ])(px);   //  destructor
         _delete(px);
     }


     
//  
      return  ;



? 关键词所带来的差?A Keyword Distinction)

    讨论了class ?struct 的差异和选择

? 对象的差? A Object Distinction)

    1. C++E序设计模型支持三种programming paradigms.
    a. E序模型(procedural model) 是?C 一栯行编E?br />    b. 抽象数据cd模型(abstract data type model, ADT) 用对象进行编E?br />    c. 面向对象模型(object-oriented model)
    模型中有一些彼此相关的cdQ通过一个抽象的base class被封装v?也就是:接口)。类型之间的操作是通过接口q行的?/p>

    Ua的以一Uparadigm写程序是好的.(哈哈Q好像这不太可能Q我q做不到)

   ? 面向对象模型(object-oriented model)
    a . C++中多态支持性的支持是通过: pointer ?reference来实现的.
    多态通过下面三种Ҏ来支?
        i. l由一l隐含的转化操作:   shape *ps = new circle();
        ii. l由virtual function 机制  ps->rotate();
        iii. l由 dynamic_cast和typeid来支?
             if(circle *pc = dynamic_cast<circle*>(ps)) ...
   多态内存需?br />       i. ?nonstatic data members 的d大小
       ii. M字节寚w的额外填?padding)
       iii. 支持virtual 而生的额外负担
    
    b. 指针的类?br />    "指向不同cd的各指针"的差异,不在于其指针的表C法不同Q也不在于其内容的不同, 而是其寻址出来的object的类型不同。也是?指针cd"会教导编译器如何解释某个特定地址中的内存内容及其大小.

    c.  加上多态之?Adding Polymorphism)
    以如下ؓ?    

 1 class  Bear :  public  ZooAnimal
 2
 3 public
 4     Bear(); 
 5      ~ Bear(); 
 6
 7      //   
 8      void  rotate(); 
 9      virtual   void  dance(); 
10
11      //   
12 protected
13      enum  Dances   }
14
15     Dances dances_known; 
16      int  cell_block; 
17 }

18
19 ///
20 Bear b(  " Yogi "  ); 
21 Bear  * pb  =   & b; 
22 Bear  & rb  =   * pb; 
23

    具体的内存布局如?br />    
    1.5 Layout of Object and Pointer of Derived Class.JPG

    //
    现有   

1 Bear b;
2 ZooAnimal *pz = &b;
3 Bear *pb = &b;
4 

以上每个都指向Bear object的第一个byteQ?font color="#ff0000" size="2">光的差别是Qpb所늛的地址包含整个的Bear object, 而pz所늛的地址只包含Bear object中的 ZooAnimal subobject部分。你只能用pz来处理Bear中的virtual functions, 而不能直接的处理Bear中的其他Mmembers.
    注意pz的类型将在编译时定以下两点:
     i. pz固定的可用接?br />     ii. pz的接口的access levelQ因为子cȝaccess level可能是不同于基类的,~译时会是否可以{换?/p>

    e. 对象赋值问?br /> 

 Bear b; 
 ZooAnimal za 
=  b; 

 
//  ZooAnimal::rotate() invoked 
 za.rotate(); 


    q里有两个问?br />    i. zaZ么调用的是ZoomAnimal::rotate的实体而不?Bear的实?
   {:zaq不是一个Bear, 它只是一个ZoomAnimal, 多态的q种Ҏ不能用在直接存取的objects上。所以?za.rotate()调用只能?ZooAnimal::rotate()

    ii. 如果初始化函数将一个object的内容完全拷贝到另一个object中去Qؓ什么za的vpt不是指向Bear的virtual table呢?
    {:~译器在初始化或赋值操作时Q如果某个object含有一个或多个vptrs, 那么q些vptrs的内容不会被原对象初始化或改?
 例如上例?ZooAnimal za = b, q里的vptrq不会被 b 的vptr所替代.
   
   


   


   

 

 

 



猩猩 2006-04-18 17:31 发表评论
]]>
Ʒþþþþ֣ݹ˾| 鶹ŷۺϾþ| һƷþð͹| þˬˬAV | þùƵ| þþƷŷƬ| 99ȾƷþֻоƷ| ɫۺϾþۺ| þþƷһ| 99þ99þ| þþž޾Ʒ| ܻƺ۵վþmimiɫ| þþĻ| þݺҹҹavapp| Ұ¾þһ| Ļþ| ˾þۺ| þAvԴվ| Ʒþþþþþ| 99þֻоƷ| ٸþĻ| AëƬþþƷ| þþѾƷre6| ˾þþþƷ| þþƷƷƾ | ƷŷþþӰ| 99ƷþþƷһ| ƷŮþþ| ɫþˬˬƬaV| þþþĻɫ| þþþƷһ | ޹Ʒþþò| þþþëƬ| 99Ʒ˾þþô߽| ŷ˾þô߽ۺ| ˾ƷѾþþþ| ŷһþþþþþôƬ| þþƷ޾Ʒɫ | www.þþƷ| þþþ޾Ʒվ | ƷѾþþþùһ|