继承与多态

继承

继承的本质是复用,也就是沿用父类的变量和作用域,并对其做出的扩展。它会使用一个叫做继承列表的符号(:)来将两个类链接起来。例如:
class student : public people,就是在student类中沿用并扩展了people类。

在习惯上我们将被继承的类叫做基类(父类),继承的类叫做派生类(基类)。
派生类(子类)=》基类(父类),派生类继承了基类
基类=》派生类,基类派生了派生类

继承的方式有三种:
public:共有(任意位置)
protected:保护(子类类和本类类)
private:私有(本类类)

下面用一段代码来更清楚的了解派生类和基类:

class base//基类
{
   
public:
	base(int a=0)
		:ma(a)
	{
   }
protected:
	int ma;
};
class derve :public base//派生类
{
   
public:
	derve(int b=0)
		:mb(b)
	{
   }
private:
	int mb;
};

可以看到,在基类中定义中了四个字节大小的变量a,在派生类中定义了四个字节大小的变量b。那么在派生类继承基类后,会将基类中的变量a也继承过来。除了通过打印的方法可以知道派生类中的大小,还可以通过命令提示符来查看派生类中空间结构的存放。(具体操作在通过命令提示符查看c++中类的构造可以看到)
在这里插入图片描述
可以看到,在派生类中总共有8个字节大小的数据。总结如下:
派生类的内存布局:
1.派生类会继承基类中的变量
2.基类的布局优先于派生类的布局(派生类要依靠基类的变量来操作)
3.除了成员变量以外作用域也会被继承
此外派生类都可以继承基类除构造析构以外的所有成员,例如:
1.普通成员变量
2.普通成员方法
3.静态成员变量
4.静态成员方法
5.作用域
6.类型
派生类函数的构造析构顺序
调用构造函数:
1.调用基类构造
2.调用派生类构造
调用析构函数:
1.调用派生类
2.调用基类构造
3.释放内存
类和类的关系:
1.组合: a part of has_a
像链表类和节点类的关系,节点是链表的一部分
2.继承: a kinfd of is_a
class people
class student : public people
鸟和喜鹊,猫和动物,人和学生
3.代理
限制底层接口对外提供特性

同名函数的关系:
1.重载:同名不同参,同作用域
2.隐藏:同名不同作用域(继承关系)。注意,派生类中同名的函数会隐藏基类中所有的同名函数
3.覆盖:派生类中同名同参的虚函数覆盖掉基类中同名同参的虚函数。

基类和派生类的指向:只允许基类指向派生类
原因:派生类中继承了基类,里面有基类的数据。但是基类中没有派生类的数据。

多态

概念:同一接口(函数名),不同形态(功能不同)。函数名相同,传入的参数不同(函数重载就是一种多态),
多态分为三种:
1.静多态
编译阶段确定函数的调用
2.动多态(默认动多态)
运行阶段确定函数的调用,通过函数的入口地址来确定
函数的入口地址存放在符号表中,以数据的方式加载进来
在编译阶段将入口地址拷贝一份至数据段
虚函数(virtual)机制提供支持
3.宏多态
预编译阶段确定函数的调用,但是因为宏是不安全的,所以一般不提倡这种做法

虚函数的处理机制

虚函数:虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
操作方法:只需要在一个函数前面加上virtual关键字即可,它是在运行阶段编译的。但是我们知道在运行阶段我们只将.data段和.text段传入到内存中,而虚函数的入口地址是放在符号表中的。所以我们会将虚函数的函数入口地址拷贝一份放入到一个叫.ratable(只读数据段)中,然后将函数入口地址存放到虚函数表中,最后再运行阶段传入到内存中去。

vftable和vfptr

当一个类中有虚函数存在时,就会相应的生成一个虚函数表(vftable),里面存放了对象的类型信息、相对偏移、虚函数的入口地址
虚函数表的结构如下:
RTTI:运行时类型信息,运行阶段确定类型
偏移:虚函数指针相对于整体作用域的偏移(0-vfptr = 偏移)
虚函数入口地址:在运行阶段会传给寄存器(下面有讲)
那既然有一个虚函数表,我们的对象就需要去访问它,这时系统就会给我们生成一个4个字节大小的虚函数指针(vfptr)来指向它,在调动虚函数时,我们会通过虚函数指针去访问到虚函数表中的信息。
大概流程图如下,(参考下面的代码)base* pb = new derve(10);:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值