c++探险--有虚函数时的继承

  1. 父类没有虚函数
    我们都知道子类在继承父类的时候,会将父类的变量和虚表指针继承下来保存到自己的内存里(即使父类private变量的内存也会继承下来,只会无法访问到),也就是子类对象内存中存储着一个父类对象。如果使菱形继承,那么"菱形"底部的类就会存储两份"菱形"顶端的类对象内存,通过虚继承可优化成一份,暂且不表。
class Base {
public:  int a;
private: int b;
};
class Sub : public Base {
int c;
};
Sub class Base int a int b int c
  1. 父类有虚函数
    如果父类中有虚函数,那么就会有虚函数表存储在内存中,父类对象会生成一个虚表指针放在内存的开始位置。
class Base {
public:  int a;
		 virtual void base_func() {}
		 virtual void base_func_other() {}
private: int b;
};
class Sub : public Base {
		 int c;
		 virtual void base_func() {}
		 virtual void sub_func() {}
};
Sub +class Base vfptr int a int b int c Sub_vftable & Sub_meta & Sub::base_func &Base::base_func_other &Sub::sub_func 虚表
  • 多态类的继承在运行时,会拷贝一份虚函数表放到内存里(父类虚表仍存在),将虚表中重写过的方法地址用子类中的地址替换。同时子类对象会将父类对象的虚表指针继承下来,指向子类虚表。
  • 因此子类虚表如图。
    • 首先Sub_meta存储着运行时对象的类型信息(如果对象时Base类型就是Base_meta),运行时typeid会根据此来计算类型。
    • base_func被子类重写了,因此换成子类中的函数地址。base_func_other仍然是基类中的地址。sub_func是子类新定义的虚函数,是子类中的地址。
  1. 灵活运用多态
    变量不能表现多态,虚函数可以表现多态。
class Base {
public:  
		 virtual void process() {
		 	send_request();
		 	get_response();
		}
		 virtual void send_request() {}
		 virtual void get_response() {}
private: int b;
};
class Sub : public Base {
public:
		 virtual void process() {
		 	Base::process();
		}
		 virtual void send_request() {}
		 virtual void get_response() {}
};

Base* b = new Sub;
b->process();

首先会调用Base::process();这种指定了类名,会直接找到Base中process()的地址,执行send_request()和get_response()。然后编译器会去查这两个函数的地址,发现是虚函数,就从对象(Sub对象)虚表中查,最终调用Sub中的两个函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值