C++ FAQ Lite[22]--继承(抽象基类)(更新)

原创 2001年04月30日 12:19:00

[22] 继承 — 抽象基类(ABCs)
(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)

简体中文版翻译:申旻nicrosoft@sunistudio.com东日制作室东日文档


FAQs in section [22]:


[22.1] 将接口和实现分离的作用是什么?

接口是公司最有价值的资源。设计接口比用一堆类来实现这个接口更费时间。而且接口需要更昂贵的人力的时间。

既然接口如此有价值,它们应该被保护,以免因为数据结构和其他实现的改变而被破坏。因此,应该将接口和实现分离。

TopBottomPrevious sectionNext section ]


[22.2] 在C++中如何分离接口和实现(就象 Modula-2)?

使用ABC。(译注:即抽象基类 abstract base class)

TopBottomPrevious sectionNext section ]


[22.3] 什么是 ABC? UPDATED!

[Recently renamed "subclass" to "derived class" (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes.]

抽象基类(abstract base class)。

在设计层次,抽象基类(ABC)对应于抽象概念。如果你问一个机修工他是否修理交通工具,他可能想知道你所说的是哪种交通工具。他不修理航天飞机、远洋轮、自行车或核潜艇。问题在于“交通工具”是一个抽象概念(例如,除非你知道你要建造哪种交通工具,否则你无法建造一个“交通工具”)。在C++中,Vehicle(交通工具)类是一个ABC,而Bicycle(自行车),SpaceShuttle(航天飞机)等则是派生类(OceanLiner(远洋轮)是一种Vehicle)。在真实世界的OO中,ABC无处不在。

在程序语言层次上,抽象基类(ABC)是有一个或多个纯虚成员函数的类。无法建立抽象基类的对象(实例)。

TopBottomPrevious sectionNext section ]


[22.4] 什么是“纯虚”成员函数? UPDATED!

[Recently renamed "subclass" to "derived class" (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes.]

将普通类变成抽象基类(也就是ABC)的成员函数。通常只在派生类中实现它。

某些成员函数只在概念中存在,而没有合理的定义。例如,假设我让你在坐标(x,y)处画一个图形,大小为 7。你会问我:“我应该画哪种图形?”(圆,矩形,六边形等,画法都不同)。在C++中,我们必须指出 draw() 成员函数的实在物(由此用户才能在有一个Shape*或者 Shape& 的时候调用它),但我们认识到,在逻辑上,它只能在子类中被定义:

 class Shape {
 public:
   virtual void draw() const = 0;  
// = 0 表示它是 "纯虚" 的
   
// ...
 };

这个纯虚函数使 Shape 成为了ABC(抽象基类)。如果你愿意,你可以将“= 0;”语法看作为代码位于NULL指针处。因此 Shape 向它的用户承诺了一个服务,然而 Shape 无法提供任何代码来实现这个承诺。这样做使得即使基类没有足够的信息来实际定义成员函数时,也强制了任何由 Shape 派生的具体类的对象须给出成员函数。

注意,为纯虚函数提供一个实现是可能的,但是这样通常会使初学者糊涂,并且最好避免这样,直到熟练之后。

TopBottomPrevious sectionNext section ]


[22.5] 如何为包含指向(抽象)基类的指针的类定义拷贝构造函数或赋值操作符?

如果类拥有被(抽象)基类指针指向的对象,则在(抽象)基类中使用虚构造函数用法。就如同一般用法一样,在基类中声明一个纯虚方法 clone() :

 

 class Shape {
 public:
   
// ...
   virtual Shape* clone() const = 0;   
// 虚拟(拷贝)构造函数
   
// ...
 };

然后在每个派生类中实现 clone()方法:

 class Circle : public Shape {
 public:
   
// ...
   virtual Shape* clone() const { return new Circle(*this); }
   
// ...
 };
 
 class Square : public Shape {
 public:
   
// ...
   virtual Shape* clone() const { return new Square(*this); }
   
// ...
 };

现在假设每个 Fred 对象有一个 Shape对象。Fred对象自然不知道 Shape是圆还是矩形还是……。Fred的拷贝构造函数和赋值操作符将调用Shapeclone()方法来拷贝对象:

 

 class Fred {
 public:
   Fred(Shape* p) : p_(p) { assert(p != NULL); }   
// p must not be NULL
  ~Fred() { delete p_; }
   Fred(const Fred& f) : p_(f.p_->clone()) { }
   Fred& operator= (const Fred& f)
     {
       if (this != &f) {              
// 检查自赋值
         Shape* p2 = f.p_->clone();   
// Create the new one FIRST...
         delete p_;                   
// ...THEN delete the old one
         p_ = p2;
       }
       return *this;
     }
   
// ...
 private:
   Shape* p_;
 };

TopBottomPrevious sectionNext section ]


E-Mail E-mail the author
C++ FAQ LiteTable of contentsSubject indexAbout the author©Download your own copy ]
Revised Apr 8, 2001

C++ FAQ Lite[19]--继承(基础)(更新)

[19] 继承 — 基础(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)简体中文版翻...
  • Nicrosoft
  • Nicrosoft
  • 2001年04月23日 22:04
  • 919

C++ FAQ Lite[20]--继承(虚函数)(更新)

[20] 继承 — 虚函数(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)简体中文版...
  • Nicrosoft
  • Nicrosoft
  • 2001年04月25日 17:24
  • 1600

C++ FAQ Lite[24]--继承(私有和保护继承)(更新)

[24] 继承 — 私有继承和保护继承(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com...
  • Nicrosoft
  • Nicrosoft
  • 2001年06月01日 05:08
  • 1109

C++ FAQ学习笔记 22章 继承 — 抽象基类(ABCs)

等待中
  • u010278548
  • u010278548
  • 2013年08月29日 08:37
  • 437

C++抽象基类

为什么C++要定义抽象基类? C++为什么要定义抽象基类?       抽象类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并没有具体实现。抽象类不能被实例化,通常是作为基类供子类继承,子...
  • chencheng126
  • chencheng126
  • 2015年01月27日 09:52
  • 877

c++抽象类实现OC中的协议

OC中协议的实现: A中要调用B中的方法,通过delegate(代理)调用协议的方法来实现。 下面看C++中怎么实现: 一、先定义一个协议类 该类是一个抽象类 #ifndef __AppDe...
  • itpeng523
  • itpeng523
  • 2015年03月06日 18:03
  • 1074

C#抽象基类与接口的区别

导读: 类   定义新的数据类型以及这些新的数据类型进行相互操作的方法   定义方式:   class Cat   ...{   }   class Cat:object   ...{   }   C...
  • kucool
  • kucool
  • 2007年09月27日 11:10
  • 1707

问题解决:继承抽象类时出现error LINK2001 无法解析的外部符号

在编程练习中使用一个抽象类,然后通过一个类说明来继承抽象类并实现抽象类的所有成员函数。根据编程习惯,我们会在.h文件中给出函数声明,在.cpp中给出各成员函数的具体实现,在编译时出现:error LI...
  • liyuefeilong
  • liyuefeilong
  • 2015年03月20日 16:21
  • 1890

C++ FAQ Lite[23]--继承(你所不知道的)(更新)

[23] 继承 — 你所不知道的(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)简体...
  • Nicrosoft
  • Nicrosoft
  • 2001年05月26日 13:10
  • 986

C++ FAQ Lite[9]--内联函数(更新)

[9] 内联函数(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)简体中文版翻译:申旻...
  • Nicrosoft
  • Nicrosoft
  • 2001年04月16日 17:06
  • 2610
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ FAQ Lite[22]--继承(抽象基类)(更新)
举报原因:
原因补充:

(最多只允许输入30个字)