Loading

34区分接口继承和实现继承

函数接口继承与函数实现继承,在public继承之下,derived classes总是继承base class的接口。

作为class的设计者:

  1.有时我们希望derived classes只继承成员函数的接口(声明);

  2.有时我们会希望derived classes同时继承函数的接口与实现,但是又希望能够覆写(override)它们所继承的实现;

  3.有时我们希望derived classes同时继承函数的接口与实现,但是不允许覆写任何东西。

class Shape{
public:
   virtual void draw() const = 0; //pure virtual 
   virtual void error(const std::string& msg); //impure virtual 
   int objectID()  const;  //non-virtual 
};

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

public继承导致的is-a关系,导致成员函数的接口总会被继承。

在基类中三种不同的函数声明方式:

  1.声明一个pure virtual函数的目的是为了让derived classes只继承函数接口

  2.声明impure virtual 函数的目的是为了让derived classes继承该函数的接口与缺省实现。

  其接口表示每个class都必须支持一个“当遇上错误时可调用的函数”,但是每个class可自由的处理错误。如果某个class不想针对错误做出特殊行为,它可以退回到shape class提供的缺省错误行为。

  3.如果成员函数是个non-virtual函数,意味着它并不打算在derived classes中有不同行为。声明non-virtual函数的目的是为了令derived classes继承函数的接口及一份强制性实现。

   Shape::objectID的声明是让每个Shape对象都有一个用来产生对象识别码的函数,此识别码总是采用相同的计算方法,此方法

  由Shape::objectID的定义式决定,任何派生类都不应该尝试改变其行为。

 


  pure virtual函数、impure virtual 函数、non-virtual函数之间的差异,使得你得以精确指定你想要derived classes继承的东西:只继承接口、或是继承接口和一份缺省实现

、或是继承接口和一份强制实现。

  经验不足的class设计者常会犯下以下两个错误:

  virtual函数的成本:

    一个典型的程序有%80的执行时间花费在%20的代码上,这个法则十分重要。

  1.将所有的函数声明为non-virtual,这使得derived classes没有剩余的空间进行特化工作。这种是不变性凌驾于特异性

  2.将所有的成员函数声明为virtual。例如接口类。 这种是特异性凌驾于不变性

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-11-14 10:17  三只猫-  阅读(209)  评论(0编辑  收藏  举报