C++【侯捷】——— 虚指针和虚表动态绑定

C++【侯捷】——— 虚指针和虚表动态绑定

虚函数的两种用法

继承和组合中构造和析构,可以通过内存的角度进行分析。
继承关系是构造父类被包含在子类中,所以构造必须由内而外,析构方向相反。
组合关系是拥有的关系,构造函数也是由内而外,析构方向相反。
继承和组合的构造/析构函数后面编译器会加上父类的构造函数:
Container::Container():Component() { … }
继承和组合同时存在的情况下,父类和组合都存在与子类中,两个的前后关系没有规定,构造也由内而外,析构相反。先父类后组合,析构是先组合再父类。

虚指针和虚表

只有类中有虚函数,其内存对象中就会多一个指针,不管虚函数有多少个,都只有一个。子类的内存对象中有父类的part。有虚函数也是同样的关系。
从类的角度,继承会把父类的内存和成员继承下来,函数继承是继承它的调用权。
函数是一块代码,再内存中是一块,在类中虚函数会生成一个指针表,每个指针指向对应的函数段。如果子类中重写了父类的虚函数,虽然子类的虚函数表中对应函数指针会指向重写的函数地址,但是,不代表父类的旧的函数段会被覆盖,它还是在的。前面的类名不同了。

class A {
public:
  virtual void vfunc1();
  virtual void vfunc2();
  void func1();
  void func2();
}
class B {
public:
  virtual void vfunc1();
  void func1();
}
class C {
public:
  virtual void vfunc2();
  void func2();
}
```cpp
虚函数地址会有:
```cpp
A::vfunc1()  //1
A::vfunc2() //2
B::vfunc1() //3
C::vfunc2() //4

A对象的虚函数表中有两个指针,分别指向1和2
B对象的虚函数表中有两个指针,分别指向2和3
C对象的虚函数表中有两个指针,分别指向3和4
在C语言中编译器通过静态绑定的方法进行,将当前的地址保存起来,调用CALL指令跳转到调用的函数中,处理完成后再返回来。而虚函数是通过动态绑定的方法,通过对象中定的虚函数表指针找到虚函数表,再从虚函数表中找到对应的虚函数指针,然后调用起这个函数。
动态绑定(虚机制)的实现和条件:
1、必须是指针
2、指针是向上指定的,类型是父类,可以new成子类对象
3、必须是虚函数
静态绑定一定指向某个固定的地址,动态要根据具体来判断。这种动态绑定的方法就叫做多态。删改你的概念其实都是同一个概念,走的是虚指针和虚表。

this pointer

Tempate Method
父类把所有能实现的方法都实现了,生一个Serialize不知道怎么实现,留给子类来进行实现。调用的时候动态绑定,OnFileOpen方法中编译器会传一个this指针,这个指针指向的是子类的对象,这个子类可以向上转型。同事
CDocument:
OnFileOpen()
{

Serialize();

}
virtual Serialize();
class CMyDoc: pulbic CDocument
{
virtual Serialize() {…}
}
main()
{
CMyDoc myDoc;

myDoc.OnFileOpen();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值