Android C++ 系列:C++ 最佳实践 2 抽象类
1. 背景
OOP 面向对象程序设计的核心是数据抽象,继承和动态绑定。前面的文章我们介绍了使用 virtual 的虚类实现动态绑定的多态,有时候我们在做抽象时,对于抽象的实体不想让被人实例化,虚类没有这个功能,我们 Java 里面我们有抽象类,有接口来抽象一个实体的行为,而不允许被实例化,C++有没有这样的功能呢?C++怎么实现抽象类呢?
2. 纯虚函数
介绍抽象类之前我们先了解下纯虚函数:我们通过在函数体的位置,即在声明语句的分号之前,书写 = 0 就可以将一个虚函数说明为纯虚函数。和普通的虚函数不一样,一个纯虚函数无需定义。而且 = 0 只能出现在虚函数声明语句处:
我们也可以为纯虚函数提供定义,不过函数体必须定义在类的外部,不能在类的内部为一个=0 的函数提供函数体。
派生类如果定义了一个函数与基类中虚函数的名字相同但是形参列表不同,这是合法的,但是很可能不符合我们的预期。特别是在继承纯虚函数时,可能因为形参列表不匹配导致声明了新的函数,而纯虚函数没有被真正实现,怎么让编译器帮助我么实现这一点呢?
在 C++11 新标准中,我们可以使用 override 关键字来说明子类中的虚函数。如果使用 override 标记了某个函数,但是这个函数又没有覆盖已存在的虚函数,编译器就直接报错了。
3. 抽象基类
了解了纯虚函数后我们就可以定义抽象类了:含有纯虚函数的类是抽象基类。抽象基类负责定义接口,而后续的其他类可以覆盖这个接口。
我们不能直接创建一个抽象基类的对象,子类构造函数只初始化它的直接基类,这个和 Java 类似,只在子类的构造中调用 super 初始化直接子类。
抽象基类的设计可以替代我们 Java 中的接口和抽象类,如果只定义行为,就类似于 Java 中的接口,如果包含了数据则可以类比成 Java 中的抽象类。
4. 总结
通过使用数抽象,我们可以将类的接口与实现分离;使用继承,可以定义相似的类型并对其相识关系建模;使用动态绑定,可以在一定程度上忽略相识类型的区别,以统一的方式使用对象。纯虚函数是实现抽象基类的基础。本文我们介绍了纯虚函数和抽象基类,这块语法上本身比较简单,下一篇我们介绍继承时的访问控制。
版权声明: 本文为 InfoQ 作者【轻口味】的原创文章。
原文链接:【http://xie.infoq.cn/article/e51d37f5b70cdcfc13a570461】。文章转载请联系作者。
评论