C++对象模型学习笔记4 Function语意学

各种调用方式

  • {P140} C++支持三种类型的member functions: static, non-static和virtual。

non-static member function

  • {P141} C++的设计准则之一便是: non-static member function至少必须和一般的non-member function有着相同的效率。转换步骤为:
    1. 改写原型(签名), 添加一个this指针作为第一个参数。同理,如有const修饰符,相当于加在这个this上。
    2. 用this指针修改所有存取的地方。
    3. 作为一个外部函数,具有mangled过的名字

virtual function

  • {P147} 如果一个虚函数里面调用了另外一个虚函数,那么另一个虚函数无需使用虚函数表进行调用,因为已经决议到该虚函数了,所以已经确定了,可以直接调用该类有的,提高效率。

static function

  • {P151} 不可以直接存取non-static数据,不可以是const, volatile, virtual。
  • static函数可以作为callback 运用到thread上。

各种情况下的 virtual function

  • 单一继承很简单,virtual table pointer找到virtual table,按照对应的offset得到function point. eg: (*ptr->vptr[offset])(ptr)
  • {P159} 多重继承,其复杂度围绕在第二个及后继的base身上,以及“必须在执行期调整this指针”。有两种解决思路:
    1. {P161} 把virtual table的entry变成address+offset,但缺点是空间浪费,因为这样不是多重继承的虚函数表项也需要两个域。eg: (*ptr->vptr[off].faddr)(ptr+ptr->vptr[off].offset)
    2. {P162} thunk。所谓thunk是一小段assembly代码,用来 1) 以适当的offset值来调整this指针 2) 并跳到相应的virtual function。thunk技术允许virtual table slot继续内含一个简单的指针,不需要任何空间上的额外负担。虚表项中地址可以直接指向virtual function,也可以指向一个相关的thunk。eg:
Base2 *ptr = new Derived;
// 调用Derived::~D...
ptr必须向后调整sizeof(Base1)
调用对应的~D时,需要将ptr调整回到Derived.

Derived *pder = new Derived;
pder->mumble(); // Base2
需要调整pder sizeof(Base1)
  • {P169} 虚拟继承,不建议在virtual base中声明non-static data。

指向member function的指针

  • {P176} 对一个nonstatic member function取址,得到的是该函数在内存中的地址;而面对一个virtual function,得到的将是一个索引值。必须被绑定于一个class object上,才能够通过它调用函数。
class Point {
public:
	virtual ~Point();
	float x();
	float y();
	virtual float z();
}

取dtor, &Point::~Point 得到的结果是1;&Point::x和&Point::y则为地址;&Point::z是数值2;

	float (Point::*pmf)() = &Point::z;
	Point *ptr = new Point3d;
	(*ptr->vptr[(int)pmf]) (ptr);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值