📄 [24] inheritance private and protected inheritance, c++ faq lite.htm
字号:
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/coding-standards.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[24.3]></A>
<DIV class=FaqTitle>
<H3>[24.3] 我应该选谁:组合还是私有继承? <IMG alt=UPDATED!
src="[24] Inheritance private and protected inheritance, C++ FAQ Lite.files/updated.gif"></H3></DIV><SMALL><EM>[Recently
changed so it uses new-style headers and the <TT>std::</TT> syntax (on 7/00). <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#[24.5]">Click
here to go to the next FAQ in the "chain" of recent changes<!--rawtext:[24.5]:rawtext--></A>.]</EM></SMALL>
<P>尽可能用组合,万不得已才用私有继承<BR><BR>通常你不会想访问其他类的内部,而私有继承给你这样的一些的特权(和责任)。但是私有继承并不有害。只是由于它增加了别人更改某些东西时,破坏你的代码的可能性,从而使维护的花费更昂贵。<BR><BR>当你要创建一个 <TT>Fred</TT> 类,它使用了 <TT>Wilma</TT> 类的代码,并且<TT>Wilma</TT> 类的这些代码需要调用你新建的 <TT>Fred</TT> 类的成员函数。在这种情况下,<TT>Fred</TT> 调用 <TT>Wilma</TT> 的非虚函数,而<TT>Wilma</TT> 调用(通常是<A
href="http://www.sunistudio.com/cppfaq/abcs.html#[22.4]">纯虚函数</A>)被<TT>Fred</TT>重写的这些函数。这种情况,用组合是很难完成的。<BR>
<DIV
class=CodeBlock><TT> class Wilma {<BR> protected:<BR> void fredCallsWilma()<BR> {<BR> std::cout << "Wilma::fredCallsWilma()\n";<BR> wilmaCallsFred();<BR> }<BR> virtual void wilmaCallsFred() = 0; </TT><EM>// <A
href="http://www.sunistudio.com/cppfaq/abcs.html#[22.4]">纯虚函数</A></EM><TT><BR> };<BR> <BR> class Fred : private Wilma {<BR> public:<BR> void barney()<BR> {<BR> std::cout << "Fred::barney()\n";<BR> Wilma::fredCallsWilma();<BR> }<BR> protected:<BR> virtual void wilmaCallsFred()<BR> {<BR> std::cout << "Fred::wilmaCallsFred()\n";<BR> }<BR> };
</TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/coding-standards.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[24.4]></A>
<DIV class=FaqTitle>
<H3>[24.4] 从私有继承类到父类需要指针类型转换吗?</H3></DIV>
<P>一般来说,不。
<P>对于该私有继承类的成员函数或者<A
href="http://www.sunistudio.com/cppfaq/friends.html">友元</A>来说,和基类的关系是已知的,并且这种从<TT>PrivatelyDer*</TT> 到 <TT>Base*</TT> (或 <TT>PrivatelyDer&</TT> 到 <TT>Base&</TT>)的向上转换是安全的,不需要也不推荐进行类型转换。<BR><BR>然而,对于该私有继承类(<TT>PrivatelyDer</TT>)的用户来说,应该避免这种不安全的转换。因为它基于<TT>PrivatelyDer</TT>的私有实现,它可以自行改变。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/coding-standards.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[24.5]></A>
<DIV class=FaqTitle>
<H3>[24.5] 保护继承和私有继承的关系是什么?<IMG alt=UPDATED!
src="[24] Inheritance private and protected inheritance, 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/private-inheritance.html#[24.6]">Click
here to go to the next FAQ in the "chain" of recent changes<!--rawtext:[24.6]:rawtext--></A>.]</EM></SMALL>
<P>相同点:都允许重写私有/保护基类的<A
href="http://www.sunistudio.com/cppfaq/virtual-functions.html">虚函数</A>,都不表明派生类“是一种(a
kind-of)”基类。
<P>不同点:保护继承允许派生类的派生类知道继承关系。如此,子孙类可以有效的得知祖先类的实现细节。这样既有好处(它允许保护继承的子类使用它和保护基类的关联)也有代价(保护派生类不能在无潜在破坏更深派生类的情况下改变这种关联)。
<P>保护继承使用 <TT>: protected</TT> 语法:
<P>
<DIV
class=CodeBlock><TT> class Car : protected Engine {<BR> public:<BR> </TT><EM>// ...</EM><TT><BR> };
</TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/coding-standards.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[24.6]></A>
<DIV class=FaqTitle>
<H3>[24.6] 私有继承和保护继承的访问规则是什么?<IMG alt=UPDATED!
src="[24] Inheritance private and protected inheritance, 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/coding-standards.html#[25.1]">Click here
to go to the next FAQ in the "chain" of recent changes<!--rawtext:[25.1]:rawtext--></A>.]</EM></SMALL>
<P>以这些类为例:
<P>
<DIV
class=CodeBlock><TT> class B { </TT><EM>/*...*/</EM><TT> };<BR> class D_priv : private B { </TT><EM>/*...*/</EM><TT> };<BR> class D_prot : protected B { </TT><EM>/*...*/</EM><TT> };<BR> class D_publ : public B { </TT><EM>/*...*/</EM><TT> };<BR> class UserClass { B b; </TT><EM>/*...*/</EM><TT> };
</TT></DIV>
<P>子类都不能访问 <TT>B</TT> 的私有部分。在 <TT>D_priv</TT>中,B 的公有和保护部分都是私有的。在 <TT>D_prot</TT>中,<TT>B</TT> 的公有和保护部分都是保护的。在 <TT>D_publ</TT> 中,<TT>B</TT> 的公有部分是公有的,<TT>B</TT> 的保护部分是保护的(<TT>D_publ</TT> 是一种 <TT>B</TT>)。<TT>UserClass</TT> 类仅仅可以访问 <TT>B</TT> 的公有部分。<BR><BR>要使 <TT>B</TT> 的公有成员在 <TT>D_priv</TT> 或 <TT>D_prot</TT>中也是公有的,则使用 <TT>B::</TT> 前缀声明成员的名称。例如,要使 <TT>B::f(int,float)</TT>成员在 <TT>D_prot</TT>中公有,应该这样写:<BR>
<DIV
class=CodeBlock><TT> class D_prot : protected B {<BR> public:<BR> using B::f; </TT><EM>// 注意: 不是 <TT>using B::f(int,float)</TT></EM><TT><BR> };
</TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#top">Top</A>
| <A
href="http://www.sunistudio.com/cppfaq/private-inheritance.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/strange-inheritance.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/coding-standards.html">Next section</A>
]</SMALL>
<HR>
<P><A name=bottom></A><A href="mailto:cline@parashift.com"><IMG height=26
alt=E-Mail
src="[24] Inheritance private and protected inheritance, C++ FAQ Lite.files/mbox.gif"
width=89> E-mail the author</A><BR>[ <A
href="http://www.sunistudio.com/cppfaq/index.html"><EM>C++ FAQ Lite</EM></A>
| <A
href="http://www.sunistudio.com/cppfaq/index.html#table-of-contents">Table of contents</A>
| <A
href="http://www.sunistudio.com/cppfaq/subject-index.html">Subject index</A>
| <A
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.1]">About the author</A>
| <A
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.2]">©</A>
| <A
href="http://www.sunistudio.com/cppfaq/on-line-availability.html#[2.2]">Download your own copy</A> ]<BR><SMALL>Revised
Apr 8, 2001</SMALL> </P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -