高山流水

----- 要黑就黑彻底

Inside The C++ Object Model 学习笔记--The Semantics of Function

Chapter 4.  The Semantics of Function: Function 语意学

4.1 Member 函数的各种调用方式
1. Nonstatic Member Function(非静态成员函数)
    要做如下的转换:
    (1) 改写函数的原形, 安插一个参数到member function中, 用于提供一个存取管道, 使class object 得以调用该函数, 这个额外的指针称之为: this指针.
    如:  
 Point3d::magnitude()  会转换为:  Point3d::magnitude(Point3d *const  this)

    (2)  对函数内每一个针对nostatic data member的存取操作改经由this指针来存取.
     如:
           return sqrt(
  this->_x  *  this->_x  + this->y * this->_y  + this->_z * this->_z;
    (3)  将对member function 重写一个外部函数, 对函数名称进行"mangling"处理, 使它生成一个独一无二的名称
   
2. Virtual Member Function(虚拟成员函数)
     例如:
  ptr->normalize();
  它将被转化为如下的调用:
 ( * ptr->vptr[ 1 ])( ptr );
 这里有几点说明: 
 i.  vptr是由编译器生成的指针,指向virtual table
 ii.  1 这里是virtual table slot 的索引值,它关联到nomalize这个函数
 iii.  第二个ptr表示this指针

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

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

2. 多重继承下的Virtual Functions
    这种继承涉及到要调整this指针,并且要求不止一个vtbl和vptr,同时要好几个这种虚表和指针

3. 虚拟继承下的Virtual Functions


4.3 函数的效能

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

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

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

4. 指向 Member Functions 指针的效率


4.4 Inline Functions
1. inline functions的生成条件

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  } 

 
用下面的方式进行处理:
   (1)  直接的参数替换
 //(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      }

 

posted on 2006-10-30 14:39 猩猩 阅读(266) 评论(0)  编辑 收藏 引用 所属分类: C&C++语言


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理