区分接口继承和实现继承

本文系整理Effective C++中的条款34


首先当我们设计一个基类的时候,对于派生类的需求可能有下面几种

  1. 派生类只继承基类的接口(即函数的声明);
  2. 派生类同时继承接口和实现,并且希望能够重写(多态)自己的版本
  3. 派生类同时继承接口和实现,但是不允许重写任何东西

说这些晦涩难懂的文字,一时半会不好理解,下面分别举实例,用代码来解读这三种需求。

下面是一个展现绘图程序中各种几何图形的class继承体系:

class Shape
{
public:
    //纯虚函数
    virtual void draw()const = 0;
    //普通的虚函数
    virtual void error(const std::string& msg);
    普通函数
    int objectID()const;
    ...
};

class Rectangle:public Shape{
  ...};
class Ellispse:public Shape{
  ...};

这里首先说下,因为virtual void draw()const = 0; 是一个纯虚函数,从而使Shape类变为一个抽象类,即不能实例化出对象。

纯虚函数的声明:virtual + 函数返回值+函数名,在函数的后面紧跟=0。

这样就导致客户不能实例化出Shape的对象,只能实例化出其派生类的对象。但是基类还是影响了所有以public方式继承它的派生类,因为成员函数的接口总是被继承,public继承意味着is-a的关系。即保证任何一个对基类为真的事件,一定也对其派生类为真。

pure virtual(纯虚函数)的特性:

  1. 在抽象类中通常没有定义
  2. 必须被任何”继承了它们”的具体class重新声明

这就意味着声明一个pure virtual函数的目的是为了让派生类只继承函数的接口

但是令人意外的是,我们竟然可以为pure virtual函数提供定义,也就是说你可以为Shape::draw供应一份实现代码,c++并不会发出怨言,但是调用它的唯一途径是”调用时指明其class名称”

如下实例:

Shape* ps = new Shape;       <
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值