设为首页 加入收藏

TOP

C++继承与面向对象设计(三)
2014-07-19 23:03:06 来源: 作者: 【 】 浏览:240
Tags:继承 面向 对象 设计

 

  如果我们想在子类中继承那些重载函数,并重写其中的一部分(像本例中的mf1和mf3),那么可以使用using语句

  让Base class内名为mf1和mf3的所有东西(所有重载函数)在Derived作用域内都是可见的。

  class Base {

  private:

  int x;

  public:

  Base() {};

  virtual void mf1() = 0;

  virtual void mf1( int m ) { std::cout << "Base mf1 int: "<< m << std::endl; } ;

  virtual void mf2() { std::cout << "Base mf2 " << std::endl; };

  void mf3() { std::cout << "Base mf3" << std::endl;};

  void mf3( double m ) { std::cout << "Base mf3 double:" << m << std::endl; };

  };

  class Derived : public Base {

  public:

  using Base::mf1; // 让Base class内名为mf1和mf3的所有东西(所有重载函数)

  using Base::mf3; // 在Derived作用域内都是可见的。

  virtual void mf1() { std::cout << "Derived mf1" << std::endl; };

  void mf3() { std::cout << "Derived mf3" << std::endl; };

  void mf4() { std::cout << "Derived mf4" << std::endl; };

  };

  调用:

  Derived* d = new Derived();

  d->mf1();

  d->mf1(1);

  d->mf2();

  d->mf3();

  d->mf3(1);

  d->mf4();

  运行截图:

clipboard

  上面这种技术告诉我们如何继承所有重载函数,实现is-a的关系。

  有时候我们并不想继承base classes的所有函数,而是用public继承和名字遮掩规则又不符合public继承所包含的is-a关系。

  因此,这里介绍一种转交函数技术,很简单,看一个例子就懂了。

  class Base {

  public:

  virtual void mf1() = 0;

  virtual void mf1(int );

  ....

  };

  class Derived : private Base {

  public:

  virtual void mf1() { Base::mf1(); } // 转交函数

  ......

  };

  小结:

  derived classes内的名称会遮掩base classes内的所有相同名称的重载函数,在public继承下这个机制并不希望发挥作用。

  可使用using声明式或转交函数来调用被遮掩的重载函数。

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

  选择继承的集中情况:

  a:希望derived classes只继承成员函数的接口

  b:希望derived classes同时继承函数的接口和实现,又希望能够重写它们所继承的实现

  c:希望derived classes同时继承函数的藉口和实现,并且不允许重写任何东西

  看一个几何图形例子:

  class Shape {

  public:

  virtual void draw() const = 0;

  virtual void error(const std::string& msg);

  int objectID() const;

  };

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

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

  首先考虑纯虚函数draw

  pure virtual函数有两个最突出的特征:

  它们必须被任何“继承了它们”的子类重新声明

  它们在抽象class中通常没有定义

  综合上面两个特征:声明一个纯虚函数的目的是为了让derived class只继承函数接口

  满足了本节开头的情景a。

  考虑虚函数error。

  虚函数的目的是让derived classes继承该函数的接口和缺省实现。满足了情景b。

  最后,考虑non-virtual函数objectID。

  声明non-virtual函数的目的是为了令derived classes继承函数的接口及一份强制性实现。

  对应了情景c。

  纯虚函数、虚函数和非虚函数使得你可以精确地指定你想要derived classes继承的东西。

  小结:

  接口继承和实现继承不同。在public继承之下,derived classes总是继承base class的接口

  pure virtual函数只具体指定接口继承。

  virtual 函数具体指定接口继承及缺省实现继承。

  non-virtual函数具体指定接口继承以及强制性实现继承。

          

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇libjingle线程机制 下一篇vc++教程之win7下基址定位处理

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·About - Redis (2025-12-26 08:20:56)
·Redis: A Comprehens (2025-12-26 08:20:53)
·Redis - The Real-ti (2025-12-26 08:20:50)
·Bash 脚本教程——Li (2025-12-26 07:53:35)
·实战篇!Linux shell (2025-12-26 07:53:32)