天天看点

万能的函数 之 接口继承 实现继承~~~

在public继承中,(public 继承表示的关系是 “is  a ” 的关系),其类中定义的函数主要有三类:pure

virtual函数,impure virtual函数以及non-virtual函数,这三种函数决定了public继承中的两个重要概念 : “ 函数接口继承” 以及 “函数实现继承”。那么接下来将针对这样一个不简单的问题做一些简介。

考虑如下的类定义:

class shape{

public:

   virtual void show() const = 0;

   virtual void error(const string &) ;

   int getid() const;

  ....

};

class rectangular : public shape { ...  };

class ellipse : public shape { ... } ;

对于上述类,首先做一些简单的说明:

shape是抽象类,因为其中含有纯虚函数( show函数 ), 抽象类不能定义对象,值得注意的是,虽然show函数是纯虚函数,但是并不表示shape不可以为其定义函数体。shape可以为show函数定义函数体,但是对该函数的调用显然不能由对象来调用(因为shape不能定义对象),因此只能

shape::show() ;来调用。

接下来,就是重要的部分了。

身为class的设计者,有时候希望derived class只继承基类的成员函数的接口,有时候又需要同时继承函数的接口以及实现,有时候又需要重写它们所继承的实现,有时候又希望derived同时继承接口与实现,并且不允许重写。

这些复杂的关系,接下来根据上述类的定义一步一步的解析:

shape的成员函数的接口总是被继承。 由于 public 继承的 “is a   ” 关系,也就是说任何可以施加到base class上的行为都可以施加到derived class身上。至于derived class如何使用他们,这便与 上述3种 virtual 函数有关。

首先,pure  virtual 纯虚函数。 它必须被任何继承了它的class重新生命,并且定义,因为他们在抽象class类通常没有定义(只是通常,原因见上)。

  1  声明pure  virtual  函数  是为了让derived class继承它的接口(也没有函数体可以继承 啊~~)。只是告诉 derived class自行去去定义自己的实现。

  2   声明impure virtual函数 是为了让derived class继承它的接口以及缺省实现(当然derived class也可以自己重新实现,多态~~)

但是,这样会遇到问题,如果新添加的derived class忘记定义自己的impure virtual函数体,也就意味着它直接使用base class的定义,这可能违背本身derived class的操作,造成意想不到的结果。对于这种问题,我们可以使用   pure  virtual   + default action来完成。例如下面的代码:

因此,使用  pure  virtual   + default action来改进,有:

现在新添加的secc航线,就必须自己定义fly函数了。

值得注意的是:上面的defaultfly函数是non-virtual的,因为没有任何函数需要重新定义它~~

试想,如果 defaultfly 函数是virtual的,那么某些类忘记定义了怎么办,额~~好熟悉的话,又得循环回去了~~

注意,在上面提到过pure virtual函数也是可以有定义体的,那么我们就可以不用声明 defaultfly 函数了,实现接下来的部分:

最后,是那个non-virtual的函数,很简单,derived class 不能重新定义,只能无条件的继承该函数的接口与实现。

综上所述:定义virtual (pure / impure)以及non-virtual 是取决于类的设计者的意图:

在public 继承下,derived class 总是继承base class的全部接口。

pure virtual函数只指定了继承的接口。

impure virtual函数指定了继承接口以及一份缺省实现。

non-virtual函数则指定了继承接口以及一份强制的实现。

继续阅读