C++继承机制

从语言和概念的角度来说,子类继承父类是继承了所有protected和public非static成员(static成员是共享而不是继承),而成员包括函数和数据。所以从概念上来说,成员函数和成员变量都被继承了。
从实现上来说,实现要在外显上不违反概念,在内部可以非常随意。所有的实现子类继承父类成员函数只是子类共享了父类的函数,没有两份拷贝。编译器知道父类的某成员函数的地址,那么在子类调用父类的该方法时,编译器只要产生
call 函数地址 的代码就可以调用父类的方法,完全没有必要保留两份拷贝。
换句话来说,非虚方法的调用在编译时就已经确定了,编译器掌握一切信息。编译器选择最高效的实现(只保留一份函数拷贝)来符合C++语言概念。从逻辑上认为子类继承了父类的方法。

对虚函数,如果是在子类对象上用.操作符调用虚函数,那么编译器可以确定函数地址,此时不需要使用虚函数调用机制。只有在基类指针上用->操作符调用虚函数时,才会使用虚函数调用机制。此时编译器不知道基类指针指向具体什么类型的对象,所以它不知道到底调用哪个函数,它产生类似如下代码:
call [vftable + functionoffset]
也就是通过虚函数表中对应函数偏移来调用,虚函数表的布局是编译器已知的。当具体某个对象构造时,他们初始化虚表使得其中指针都指向自己的虚函数。这样就通过这个实现来满足了C++的虚函数概念。

举个例子:
class base {
  private:
   int member1;
  protected:
   int member2;
  public:
   int fun();
   virtual int virtualfun();
};

class derive : public base {
   public:
    int member;
   public:
    virtual int virtualfun();
};

在代码中使用:derive test;
(以微软c/c++编译器为例)那么test在内存中可能是如下布局:
110000  vftable----------->112000
110004  base::member1
110008  base::member2
11000c  derive::member
----------------------------
112000  (vftable[0])derive::virtualfun------>410000
----------------------------
410000   int derive::virtualfun(){ ... }
410500   int base::virtualfun(){ ... }
411000   int base::fun(){ ... }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值