📄 effective c++ 2e item35.htm
字号:
<P> ...</P>
<P>};</P>
<P>void makeBigger(Rectangle&
r) //
增加r面积的函数<BR>{
<BR> int oldHeight = r.height();</P>
<P> r.setWidth(r.width() +
10); // 对r的宽度增加10</P>
<P> assert(r.height() == oldHeight); //
断言r的高度未变<BR>}
</P>
<P>很明显,断言永远不会失败。makeBigger只是改变了r的宽度,高度从没被修改过。</P>
<P>现在看下面的代码,它采用了公有继承,使得正方形可以被当作矩形来处理:</P>
<P>class Square: public Rectangle { ... };</P>
<P>Square s;</P>
<P>...</P>
<P>assert(s.width() == s.height()); //
这对所有正方形都成立</P>
<P><BR>makeBigger(s);
// 通过继承,s "是一个"
矩形<BR>
//
所以可以增加它的面积<BR>
<BR>assert(s.width() == s.height()); //
这还是对所有正方形成立</P>
<P>很明显,和前面的断言一样,后面的这个断言也永远不会失败。因为根据定义,正方形的宽和高应该相等。</P>
<P>那么现在有一个问题。我们怎么协调下面的断言呢?</P>
<P>· 调用makeBigger前,s的宽和高相等;<BR>· makeBigger内部,s的宽度被改变,高度未变;<BR>·
从makeBigger返回后,s的高度又和宽度相等。(注意s是通过引用传给makeBigger的,所以makeBigger修改了s本身,而不是s的拷贝)</P>
<P>怎么样?</P>
<P>欢迎加入公有继承的精彩世界,在这里,你在其它研究领域养成的直觉 ---- 包括数学 ----
可能不象你所期望的那样为你效劳。对于上面例子中的情况来说,最根本的问题在于:对矩形适用的规则(宽度的改变和高度没关系)不适用于正方形(宽度和高度必须相同)。但公有继承声称:对基类对象适用的任何东西
---- 任何!----
也适用于派生类对象。在矩形和正方形的例子(以及条款40中涉及到set的一个类似的例子)中,所声称的原则不适用,所以用公有继承来表示它们的关系只会是错误。当然,编译器不会阻拦你这样做,但正如我们所看到的,它不能保证程序可以工作正常。正如每个程序员都知道的,代码通过编译并不说明它能正常工作。</P>
<P>但也不要太担心你多年积累的软件开发直觉在步入到面向对象设计时会没有用武之地。那些知识还是很有价值,但既然你在自己的设计宝库中又增加了继承这一利器,你就要用新的眼光来扩展你的专业直觉,从而指导你开发出正确无误的面向对象程序。很快,你会觉得让Penguin从Bird继承或让Square从Rectangle
继承的想法很可笑,就象现在某个人向你展示一个长达数页的函数你会觉得可笑一样。也许它是解决问题的正确方法,只是不太合适。</P>
<P>当然,"是一个" 的关系不是存在于类之间的唯一关系。类之间常见的另两个关系是 "有一个" 和
"用...来实现"。这些关系在条款40和42进行讨论。这两个关系中的某一个被不正确地表示成 "是一个"
的情况并不少见,这将导致错误的设计。所以,一定要确保自己理解这些关系的区别,以及怎么最好地用C++来表示它们。</P><BR><BR></DIV></DIV></DIV><BR><BR>
<SCRIPT src="Effective C++ 2e Item35.files/get_readnum.htm"></SCRIPT>
<TABLE align=center bgColor=#666666 border=0 cellPadding=2 cellSpacing=1
width=770>
<TBODY>
<TR>
<TH bgColor=#990000 id=white><FONT
color=#ffffff>对该文的评论</FONT></TH></TR></TBODY></TABLE><BR>
<SCRIPT language=javascript>
<!--
function isEmpty(s)
{
return ((s == null) || (s.length == 0))
}
function submit1()
{
if (isEmpty(document.add_critique.csdnname.value) || isEmpty(document.add_critique.csdnpassword.value) || isEmpty(document.add_critique.critique_content.value))
{
alert('登陆名,密码,评论不能为空!!!!') ;
return false;
}
document.add_critique.submit();
}
//-->
</SCRIPT>
<TABLE align=center bgColor=#666666 border=0 cellPadding=2 cellSpacing=1
width=770>
<TBODY>
<TR>
<TH bgColor=#990000 id=white><FONT
color=#ffffff>发表评论</FONT></TH></TR></TBODY></TABLE>
<TABLE align=center bgColor=#ffffff border=0 cellPadding=2 cellSpacing=1
width=770>
<TBODY>
<TR>
<TD>
<FORM action=/develop/add_critique.asp method=post
name=add_critique><INPUT name=critique_add type=hidden value=add> <INPUT
name=from type=hidden value=9254> 评论人: <INPUT name=csdnname>
密码: <INPUT name=csdnpassword type=password>
评论:<BR> <TEXTAREA cols=100 name=critique_content rows=8></TEXTAREA><BR>
<INPUT name=ubmit onclick=javascript:submit1(); type=button value=发表评论>
<INPUT name=id type=hidden value=9254> </FORM></TD></TR></TBODY></TABLE>
<TABLE border=0 width=770>
<TBODY>
<TR>
<TD>
<TABLE border=0 cellPadding=2 width=770>
<TBODY>
<TR>
<TD height=10></TD></TR>
<TR>
<TD align=left width=130><A
href="http://www.csdn.net/news/looknews.asp?id=2313"
target=_blank><IMG border=0
src="http://www.csdn.net/job/images/csdn_job.gif"></A> </TD>
<TD align=middle width=510>
<OBJECT classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000
codeBase=http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0
height=60 id=Movie1 width=468><PARAM NAME="movie" VALUE="http://www.csdn.net/images/ad/csdn_media.swf"><PARAM NAME="quality" VALUE="high">
<EMBED src="http://www.csdn.net/images/ad/csdn_media.swf"
quality=high WIDTH=468 HEIGHT=60
TYPE="application/x-shockwave-flash"
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</EMBED> </OBJECT></TD>
<TD align=middle width=130><A
href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG
border=0 src="http://www.csdn.net/images/biaoshi.gif"></A>
</TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD>
<TABLE align=default bgColor=#1f60a0 border=0 cellPadding=0 cellSpacing=0
height=20 width=770>
<TBODY>
<TR align=middle class=font13px vAlign=center>
<TD class=font13px height=2 vAlign=center width=90></TD>
<TD rowSpan=2 width=2><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></TD>
<TD class=font13px height=2 width=90></TD>
<TD rowSpan=2 width=3><FONT color=#ffffff><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></FONT></TD>
<TD class=font13px height=2 width=90></TD>
<TD rowSpan=2 width=2><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></TD>
<TD class=font13px height=2 width=90></TD>
<TD rowSpan=2 width=3><FONT color=#ffffff><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></FONT></TD>
<TD height=2 width=350><FONT color=#ffffff></FONT></TD>
<TD rowSpan=2 width=10><FONT color=#ffffff><IMG height=11
src="http://www.csdn.net/images/ad3.gif" width=6></FONT></TD>
<TD class=font13px height=2 width=60></TD></TR>
<TR align=middle class=font14px vAlign=center>
<TD class=font13px vAlign=center width=90><A
href="http://www.csdn.net/intro/intro.shtm"><FONT
color=#ffffff>美达美简介</FONT></A></TD>
<TD class=font13px width=90><A
href="http://www.csdn.net/intro/ad.shtm"><FONT
color=#ffffff>广告服务</FONT></A></TD>
<TD class=font13px width=90><A
href="http://www.csdn.net/English/"><FONT
color=#ffffff>英语步步高</FONT></A></TD>
<TD class=font13px width=90><A href="http://www.csdn.net/dev/"><FONT
color=#ffffff>程序员大本营</FONT></A></TD>
<TD align=right width=350><SPAN class=font13px><A
href="mailto:webmaster@csdn.net"><FONT
color=#ffffff>百联美达美科技有限公司</FONT></A></SPAN><FONT color=#ffffff><SPAN
class=font13px> </SPAN></FONT></TD>
<TD class=font13px width=60><FONT color=#ffffff>版权所有</FONT>
<SCRIPT>document.write("<img src=http://202.106.156.10/stat.asp?user=designol&refer="+escape(document.referrer)+"&cur="+escape(document.URL)+" width=0 height=0 border=0>");</SCRIPT>
</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -