首页 > 应用开发 > IT综合 > C++对象模型之四 成员函数笔记 (转)
C++对象模型之四 成员函数笔记XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
成员函数的调用方式
非静态成员函数:C++设计准则之一就是非静态成员函数至少和一般的非成员函数一样的效率。
所以编译器内化成非成员函数,其步骤 1改写函数的原型以安插一个额外的参数到成员函数中,用以提供一个存取管道,使类对象得以调用该函数。 这个参数为 this 指针。
Point3d::Mangitude( Point3d *const this);
2 将每个对非静态数据成员的存取操作改为经由this指针来存取。
{ return sqr( this->_x * this->_x+ this->_y * this->_y+ this->_z * this->_z); }
3 将成员函数重新写成一个外部函数,对函数名称进行 mangling 处理。
Extern mangitude __7Point3dFv ( regiester Piont3d *const this)
虚成员函数 register float mag = Magnitude(); è register float mag = ( *this->vptr[2]) (this);
1 编译器生成vptr指针;2 虚函数表中的索引值;3就是this 指针
静态成员函数 obj.Magnitude(); ptr->Magnitude(); 都会转化成 Magnitude__7Point3dsfv();
虚成员函数
如果类中有虚函数,就会有虚函数表指针(vptr),表格的地址,大小和内容都是编译掌握住了。
执行时要做的是在特定的虚函数表槽激活虚函数。虚函数包括:1 派生类改写基类的虚函数,2 继承基类的虚函数,3 纯虚函数。
Class Pont
{
public:
virtual ~Point();
virtual Point& mult(float)=0;
float x() const {return _x;}
virtual float y() const { return 0;}
virtual float x() const { return 0;}
protecetd:
point (float x = 0.0);
float _x;
};
2003-8-31933440.jpg">
当一个类派生自Point时,会发生什么?
1 可能它继承基类所声明的虚函数的函数实体,正确地说是该函数实体的地址会被拷贝到派生类的虚函数表相对应的槽中
2 可能 它可以使用自己的函数实体,者表示它自己的函数实体地址必须放在对应的槽中
3 可能它可以加入一个新的虚函数表,这时候虚函数表的尺寸会增大一个槽,而新的函数实体地址会被放进该槽中。
多重继承下得虚函数
复杂度围绕在第二个及后继的基类身上,以及必须在执行时调整this指针
class Base1{
public: Base1();
virtual ~Base1();
virutal void speckclearly();
virutal Base1 *clone() const;
protected: float data_Base1;
};
class Base2{
public: Base1();
virtual ~Base2();
virutal void mumble();
virutal Base1 *clone() const;
protected: float data_Base2;
};
class Derived :public Base1,public Base2
{
public:
Derived();
Virtual ~Derived();
Virtual Derived *clone() const;
Protected : float data_Derived;
};
Base2 *pbase2 = new derived;
è 调整: Derived *temp = new Derived; Base2 *pbase2 = temp ? temp + sizeof(Base1):0;
当第二个基类的指针调用派生类的虚函数时,必须在执行中完成调整。也就是offset
this+=sizeof(base1);
Derived::~Derived(this);
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10752019/viewspace-981493/ ,如需转载,请注明出处,否则将追究法律责任。