一、Member的各种调用方式
1. Nonstatic Member Functions
首先给出nonstatic member function 和 nonmember function
float magnitude3d( const Point *_this ) { ... } // nonmember function
float Point3d::magnitude3d() const { ... } // nonstatic member function对于C++中class中的非静态成员函数,都会转化成对等的 “ nonmember 函数实例 ”, 也就是
float magnitude3d( const Point3d* _this ) {
return sqrt( _this->x * _this->x +
_this->y * _this->y +
_this->z * _this->z );
}上式就是通过对 nonstatic member function
float Point3d::magnitude3d() const { ... } // nonstatic member function改写成nonmember function的过程。转化步骤如下:
- 改写函数的原型以安插一个额外的参数到member function中,此例为_this指针。以及const nonstatic member
- 对每个“nonstatic data member的存取操作” 改成this指针来存取,也就是 _this->x 等
- 将member function重新写成一个外部函数。 也就是对上式改写成类似
void normalize_7Point3dFv( register const point3d *const this, Point3d &__result )
{
register float mag = this->magnitude();
_result.Point3d::Point3d( this->x_mag, this->y_mag, this->z_mag );
return;
}
2. virtual Member funtions
ptr->normalize();会被转换为:(* ptr->vptr[1])( ptr );
- vptr即指向virtual table的指针
- 1是virtual table slot的索引值,也就是指向virtual table上的哪个函数的下标,这里是关联到normalize
- 第二个ptr表示this 指针。
3. static member function
obj.normalize();
ptr->normalize();一般都会转化为以下nonmember函数的调用,也就是// obj.normalize();
normalize_7Point3dSFv();
// ptr->normalize();
normalize_7Point3dSfv();
object_count( (Point3d*) 0);
- 它不能直接存取其class中的nonstatic members
- 它不能被申明为const , volatile 或者 virtual
- 它不需要经由class object才被调用。
&Point3d::object_count();获取的是unsigned int(*) ();而不是unsigned int( Point3d::* ) ();
二、virtual member function
Point *ptr;
ptr = new Point2d; //寻址出一个Point2d的对象
ptr = new Point3d; //寻址出一个Point3d的对象
为了支持virtual function的机制,必须首先对于多态对象有某种形式的“执行期类型判断法(runtime type resolution)”。
假如有例子如下:
Point *ptr1, *ptr2;
ptr1 = new Point2D;
ptr2 = new Point3D;
ptr1->z();
其中z()是一个virtual function, 为了在执行期调用正确的z(), 需要知道
- ptr所指对象的真实类型
- z()实例的位置
- 一个字符串或数字,表示class的类型
- 一个指针,指向某表格,表格中有程序的virtual function的执行期的地址。
- 为了找到表格,每一个class object被安插了一个由编译器内部产生的指针,指向该表格
- 为了找到函数地址,每一个virtual function被指派一个表格索引值。
- class所定义的函数实例,overriding可能存在的base class virtual function的函数实例
- 继承自base class的函数实例。即derived class决定不改写virtual function时才出现的情况
- pure_virtual_called()函数实例,扮演pure virtual function的空间保卫者角色,也可以当做执行期异常处理函数。
ptr->z();以上信息足够使得编译器将调用转化为:(*ptr->vptr[ 4 ])(ptr);唯一在执行期才能够知道的东西是:slot 4到底是指向哪个z()的实例。1. 多重继承下的virtual function
class Derived : public Base1, public Base2;其中三个类中分别有虚析构函数,成员函数mumble(), 以及对应对象的clone()函数。如Base2virtual ~Base2();
virtual void mumble();
virtual Base2 *clone() const;当执行下述语句时:Base2 *pbase2 = new Derived;此时新的Derived对象的地址必须调整以指向其Base2 subobject。编译器会产生以下代码:Derived *temp = new Derived;
Base2 *pbase2 = temp ? temp + sizeof(Base1) : 0;而当程序删除pbase2所指的对象时,如delete pbase2;此时指针将会再次被调整,以指向Derived对象的起始处。上述的offset的加法在编译时期不能直接设定,因此pbase2所指的真正对象只有在执行期才会确定。问题:符号名称的链接很慢,如何解决?
2. 虚拟继承下的virtual Functions
class Point3d : public virtual Point2d则面对于Point3d的virtual function的布局而言。参考:
深度探索C++对象模型,侯捷, 第四章 Function语意学
2万+



被折叠的 条评论
为什么被折叠?



