C++中的抽象类和接口
抽象类
抽象类用来描述一种类型应该具备的基本特征与功能, 具体如何去完成这些行为由子类通过方法重写来完成;比如动物都会跑, 但是跑这个功能具体的实现是由人/狗等等子类来实现的, 动物这个类的跑实际的实现与细节我们是无法写出来和实现的.
在C++中要实现所谓的抽象类就是需要实现通过纯虚函数实现, 如果该类存在纯虚函数的成员就是抽象类; 纯虚函数指的是只有原型的定义而没有实现的函数. 抽象类无法生成实例, 只能被继承的子类也没有实现那么也是一个抽象类.
抽象类简单代码说明
class A
{
virtual void test() = 0;
...
}
virtual
指明这是一个虚函数, =0
指明这是一个纯虚函数不需要实现;
ps: 虚函数(如果不加=0), 父类实现并可以直接使用, 同时也可以被重载后在子类中使用.
接口
所有成员函数均为纯虚函数的类并且没有定义任何成员变量的类即为接口
多态
C++中可以让一个父类指针实际指向与一个子类, 而C++中的多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
class A
{
virtual void out() = 0;
}
class B : public A
{
void out(){printf("%s\n", "B");}
}
class C : public A
{
void out(){printf("%s\n", "C");}
}
...
A *ab = new B;
A *ac = new C;
假设我们给一个函数传入类A, 但是实际可能是类B或者类C, 在调用成员函数out
时会自动调用各自不同的实现; 这就是多态
虚表
那么多态是怎么实现的呢? 如果不考虑很复杂的实现, 那么我们很简单的就可以猜到必然是使用一个指针来获取这些信息, 这就是虚表的指针; 我们可以测试一下, 一个继承了虚函数的类会比没有的多出4(或者)8个字节, 就是一个指针的大小
虚表的含义: 虚表在编译阶段构造出来的表, 每个有虚函数的类或者继承具有虚函数的基类, 编译器都会为它生成一个虚拟函数表, 虚表中的每一个元素都分别指向一个虚函数的地址; 该类所有对象都有一个虚表指针指向同一个表
ps: 笔者在网上看了一下, 发现类的内存结构中似乎第一个就是虚表的指针, 也就意味着把类指针强转为虚表的指针从而实现直接获取虚表中的函数地址。
网友评论