⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 [22] inheritance abstract base classes (abcs), c++ faq lite.htm

📁 c++faq。里面有很多关于c++的问题的解答。
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0042)http://www.sunistudio.com/cppfaq/abcs.html -->
<HTML><HEAD><TITLE>[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META http-equiv=Content-Language content=zh-cn>
<META content=abcs.html name=FILENAME>
<META content="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite" 
name=ABSTRACT>
<META content=cline@parashift.com name=OWNER>
<META content="Marshall Cline, cline@parashift.com" name=AUTHOR>
<META content="MSHTML 6.00.2462.0" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId><LINK rev=made 
href="mailto:cline@parashift.com"><LINK 
href="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite.files/cpp-faq.css" 
type=text/css rel=stylesheet></HEAD>
<BODY>
<H1><A name=top></A>[22] 继承 — 抽象基类(ABCs)<BR><SMALL><SMALL>(Part of <A 
href="http://www.sunistudio.com/cppfaq/index.html"><EM>C++ FAQ Lite</EM></A>, <A 
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.2]">Copyright&nbsp;&copy; 
1991-2001</A>, <A href="http://www.parashift.com/" target=OutsideTheFAQ>Marshall 
Cline</A>, <A 
href="mailto:cline@parashift.com">cline@parashift.com</A>)</SMALL></SMALL></H1>
<P>简体中文版翻译:<A href="http://www.sunistudio.com/nicrosoft">申旻</A>,<A 
href="mailto:nicrosoft@sunistudio.com">nicrosoft@sunistudio.com</A>(<A 
href="http://www.sunistudio.com/">东日制作室</A>,<A 
href="http://www.sunistudio.com/asp/sunidoc.asp">东日文档</A>)</P>
<HR>

<H3>FAQs in section [22]:</H3>
<UL>
  <LI><A href="http://www.sunistudio.com/cppfaq/abcs.html#[22.1]">[22.1] 
  将接口和实现分离的作用是什么?</A> 
  <LI><A href="http://www.sunistudio.com/cppfaq/abcs.html#[22.2]">[22.2] 
  在C++中如何分离接口和实现(就象&nbsp;Modula-2)?</A> 
  <LI><A href="http://www.sunistudio.com/cppfaq/abcs.html#[22.3]">[22.3] 
  什么是&nbsp;ABC?</A> <IMG alt=UPDATED! 
  src="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite.files/updated.gif"> 

  <LI><A href="http://www.sunistudio.com/cppfaq/abcs.html#[22.4]">[22.4] 
  什么是“纯虚”成员函数?</A> <IMG alt=UPDATED! 
  src="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite.files/updated.gif"> 

  <LI><A href="http://www.sunistudio.com/cppfaq/abcs.html#[22.5]">[22.5] 
  如何为包含指向(抽象)基类的指针的类定义拷贝构造函数或赋值操作符?<BR></A></LI></UL>
<HR>

<P><A name=[22.1]></A>
<DIV class=FaqTitle>
<H3>[22.1] 将接口和实现分离的作用是什么?</H3></DIV>
<P>接口是公司最有价值的资源。设计接口比用一堆类来实现这个接口更费时间。而且接口需要更昂贵的人力的时间。<BR><BR>既然接口如此有价值,它们应该被保护,以免因为数据结构和其他实现的改变而被破坏。因此,应该将接口和实现分离。 

<P><SMALL>[&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#top">Top</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#bottom">Bottom</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/proper-inheritance.html">Previous&nbsp;section</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Next&nbsp;section</A> 
]</SMALL> 
<HR>

<P><A name=[22.2]></A>
<DIV class=FaqTitle>
<H3>[22.2] 在C++中如何分离接口和实现(就象&nbsp;Modula-2)?</H3></DIV>
<P>使用<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#[22.3]">ABC</A>。(译注:即抽象基类&nbsp;abstract&nbsp;base&nbsp;class)
<P><SMALL>[&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#top">Top</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#bottom">Bottom</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/proper-inheritance.html">Previous&nbsp;section</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Next&nbsp;section</A> 
]</SMALL> 
<HR>

<P><A name=[22.3]></A>
<DIV class=FaqTitle>
<H3>[22.3] 什么是&nbsp;ABC? <IMG alt=UPDATED! 
src="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite.files/updated.gif"></H3></DIV><SMALL><EM>[Recently 
renamed "subclass" to "derived class" (on 7/00). <A 
href="http://www.sunistudio.com/cppfaq/abcs.html#[22.4]">Click here to go to the 
next FAQ in the "chain" of recent 
changes<!--rawtext:[22.4]:rawtext--></A>.]</EM></SMALL> 
<P>抽象基类(abstract base class)。
<P>在设计层次,抽象基类(ABC)对应于抽象概念。如果你问一个机修工他是否修理交通工具,他可能想知道你所说的是哪种交通工具。他不修理航天飞机、远洋轮、自行车或核潜艇。问题在于“交通工具”是一个抽象概念(例如,除非你知道你要建造哪种交通工具,否则你无法建造一个“交通工具”)。在C++中,<TT>Vehicle</TT>(交通工具)类是一个ABC,而<TT>Bicycle</TT>(自行车),<TT>SpaceShuttle</TT>(航天飞机)等则是派生类(<TT>OceanLiner(远洋轮)</TT>是一种<TT>Vehicle</TT>)。在真实世界的OO中,ABC无处不在。<BR><BR>在程序语言层次上,抽象基类(ABC)是有一个或多个<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#[22.4]">纯虚</A>成员函数的类。无法建立抽象基类的对象(实例)。 

<P><SMALL>[&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#top">Top</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#bottom">Bottom</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/proper-inheritance.html">Previous&nbsp;section</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Next&nbsp;section</A> 
]</SMALL> 
<HR>

<P><A name=[22.4]></A>
<DIV class=FaqTitle>
<H3>[22.4] 什么是“纯虚”成员函数? <IMG alt=UPDATED! 
src="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite.files/updated.gif"></H3></DIV><SMALL><EM>[Recently 
renamed "subclass" to "derived class" (on 7/00). <A 
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html#[23.1]">Click 
here to go to the next FAQ in the "chain" of recent changes<!--rawtext:[23.1]:rawtext--></A>.]</EM></SMALL> 
<P>将普通类变成抽象基类(也就是ABC)的成员函数。通常只在派生类中实现它。
<P>某些成员函数只在概念中存在,而没有合理的定义。例如,假设我让你在坐标<TT>(x,y)</TT>处画一个图形,大小为&nbsp;7。你会问我:“我应该画哪种图形?”(圆,矩形,六边形等,画法都不同)。在C++中,我们必须指出&nbsp;<TT>draw()</TT>&nbsp;成员函数的实在物(由此用户才能在有一个<TT>Shape*</TT>或者&nbsp;<TT>Shape&amp;</TT>&nbsp;的时候调用它),但我们认识到,在逻辑上,它只能在子类中被定义: 

<P>
<DIV 
class=CodeBlock><TT>&nbsp;class&nbsp;Shape&nbsp;{<BR>&nbsp;public:<BR>&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;draw()&nbsp;const&nbsp;=&nbsp;0;&nbsp;&nbsp;</TT><EM>//&nbsp;=&nbsp;0&nbsp;表示它是&nbsp;"纯虚"&nbsp;的</EM><TT><BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;}; 
</TT></DIV>
<P>这个纯虚函数使&nbsp;<TT>Shape</TT>&nbsp;成为了ABC(抽象基类)。如果你愿意,你可以将“<TT>=&nbsp;0;</TT>”语法看作为代码位于NULL指针处。因此&nbsp;<TT>Shape</TT>&nbsp;向它的用户承诺了一个服务,然而&nbsp;<TT>Shape</TT>&nbsp;无法提供任何代码来实现这个承诺。这样做使得即使基类没有足够的信息来实际定义成员函数时,也强制了任何由&nbsp;<TT>Shape</TT>&nbsp;派生的具体类的对象须给出成员函数。 

<P>注意,为纯虚函数提供一个实现是可能的,但是这样通常会使初学者糊涂,并且最好避免这样,直到熟练之后。 
<P><SMALL>[&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#top">Top</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#bottom">Bottom</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/proper-inheritance.html">Previous&nbsp;section</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Next&nbsp;section</A> 
]</SMALL> 
<HR>

<P><A name=[22.5]></A>
<DIV class=FaqTitle>
<H3>[22.5] 如何为包含指向(抽象)基类的指针的类定义拷贝构造函数或赋值操作符?</H3></DIV>
<P>如果类拥有被(抽象)基类指针指向的对象,则在(抽象)基类中使用<A 
href="http://www.sunistudio.com/cppfaq/virtual-functions.html#[20.5]">虚构造函数用法</A>。就如同一般用法一样,在基类中声明一个<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#[22.4]">纯虚</A>方法&nbsp;<TT>clone()</TT>&nbsp;:
<P> 
<DIV 
class=CodeBlock><TT>&nbsp;class&nbsp;Shape&nbsp;{<BR>&nbsp;public:<BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;&nbsp;&nbsp;virtual&nbsp;Shape*&nbsp;clone()&nbsp;const&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/virtual-functions.html#[20.5]">虚拟(拷贝)构造函数</A></EM><TT><BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;}; 
</TT></DIV>
<P>然后在每个派生类中实现&nbsp;<TT>clone()</TT>方法: 
<P>
<DIV 
class=CodeBlock><TT>&nbsp;class&nbsp;Circle&nbsp;:&nbsp;public&nbsp;Shape&nbsp;{<BR>&nbsp;public:<BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;&nbsp;&nbsp;virtual&nbsp;Shape*&nbsp;clone()&nbsp;const&nbsp;{&nbsp;return&nbsp;new&nbsp;Circle(*this);&nbsp;}<BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;};<BR>&nbsp;<BR>&nbsp;class&nbsp;Square&nbsp;:&nbsp;public&nbsp;Shape&nbsp;{<BR>&nbsp;public:<BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;&nbsp;&nbsp;virtual&nbsp;Shape*&nbsp;clone()&nbsp;const&nbsp;{&nbsp;return&nbsp;new&nbsp;Square(*this);&nbsp;}<BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;}; 
</TT></DIV>
<P>现在假设每个 <TT>Fred</TT> 
对象有一个&nbsp;<TT>Shape</TT>对象。<TT>Fred</TT>对象自然不知道&nbsp;<TT>Shape</TT>是圆还是矩形还是……。<TT>Fred</TT>的拷贝构造函数和赋值操作符将调用<TT>Shape</TT>的<TT>clone()</TT>方法来拷贝对象:
<P> 
<DIV 
class=CodeBlock><TT>&nbsp;class&nbsp;Fred&nbsp;{<BR>&nbsp;public:<BR>&nbsp;&nbsp;&nbsp;Fred(Shape*&nbsp;p)&nbsp;:&nbsp;p_(p)&nbsp;{&nbsp;assert(p&nbsp;!=&nbsp;NULL);&nbsp;}&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;<TT>p</TT>&nbsp;must&nbsp;not&nbsp;be&nbsp;<TT>NULL</TT></EM><TT><BR>&nbsp;&nbsp;~Fred()&nbsp;{&nbsp;delete&nbsp;p_;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;Fred(const&nbsp;Fred&amp;&nbsp;f)&nbsp;:&nbsp;p_(f.p_-&gt;clone())&nbsp;{&nbsp;}<BR>&nbsp;&nbsp;&nbsp;Fred&amp;&nbsp;operator=&nbsp;(const&nbsp;Fred&amp;&nbsp;f)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(this&nbsp;!=&nbsp;&amp;f)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;检查自赋值</EM><TT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shape*&nbsp;p2&nbsp;=&nbsp;f.p_-&gt;clone();&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;Create&nbsp;the&nbsp;new&nbsp;one&nbsp;FIRST...</EM><TT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;p_;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...THEN&nbsp;<TT>delete</TT>&nbsp;the&nbsp;old&nbsp;one</EM><TT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p_&nbsp;=&nbsp;p2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;*this;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;</TT><EM>//&nbsp;...</EM><TT><BR>&nbsp;private:<BR>&nbsp;&nbsp;&nbsp;Shape*&nbsp;p_;<BR>&nbsp;}; 
</TT></DIV>
<P><SMALL>[&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#top">Top</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/abcs.html#bottom">Bottom</A> |&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/proper-inheritance.html">Previous&nbsp;section</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Next&nbsp;section</A> 
]</SMALL> 
<HR>

<P><A name=bottom></A><A href="mailto:cline@parashift.com"><IMG height=26 
alt=E-Mail 
src="[22] Inheritance abstract base classes (ABCs), C++ FAQ Lite.files/mbox.gif" 
width=89>&nbsp;E-mail the author</A><BR>[&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/index.html"><EM>C++ FAQ Lite</EM></A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/index.html#table-of-contents">Table&nbsp;of&nbsp;contents</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/subject-index.html">Subject&nbsp;index</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.1]">About&nbsp;the&nbsp;author</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.2]">&copy;</A> 
|&nbsp;<A 
href="http://www.sunistudio.com/cppfaq/on-line-availability.html#[2.2]">Download&nbsp;your&nbsp;own&nbsp;copy</A>&nbsp;]<BR><SMALL>Revised 
Apr 8, 2001</SMALL> </P></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -