📄 effective c++ 2e item39.htm
字号:
<P>class BankAccount { ...
}; // 和本条款开始时一样</P>
<P>class
SavingsAccount:
// 同上<BR> public BankAccount { ... };</P>
<P>class
CheckingAccount:
// 同上<BR> public BankAccount { ... };</P>
<P>list<BankAccount*> allAccounts; //
看起来应该熟悉些了吧...</P>
<P>void error(const string& msg); //
出错处理函数;<BR>
// 见下文</P>
<P>// 嗯,至少转换很安全<BR>for (list<BankAccount*>::iterator p =
allAccounts.begin();<BR> p !=
allAccounts.end();<BR> ++p) {</P>
<P> // 尝试将*p安全转换为SavingsAccount*;<BR> // psa的定义信息见下文<BR> if
(SavingsAccount *psa =<BR>
dynamic_cast<SavingsAccount*>(*p)) {<BR>
psa->creditInterest();<BR> }</P>
<P> // 尝试将它安全转换为CheckingAccount<BR> else if (CheckingAccount *pca
=<BR>
dynamic_cast<CheckingAccount*>(*p)) {<BR>
pca->creditInterest();<BR> }</P>
<P> // 未知的帐户类型<BR> else {<BR> error("Unknown
account type!");<BR> }<BR>}</P>
<P>这种方法远不够理想,但至少可以检测到转换失败,而用dynamic_cast是无法做到的。但要注意,对所有转换都失败的情况也要检查。这正是上面代码中最后一个else语句的用意所在。采用虚函数,就不必进行这样的检查,因为每个虚函数调用必然都会被解析为某个函数。然而,一旦打算进行转换,这一切好处都化为乌有。例如,如果某个人在类层次结构中增加了一种新类型的帐户,但又忘了更新上面的代码,所有对它的转换就会失败。所以,处理这种可能发生的情况十分重要。大部分情况下,并非所有的转换都会失败;但是,一旦允许转换,再好的程序员也会碰上麻烦。</P>
<P>上面if语句的条件部分,有些看上去象变量定义的东西,看到它你是不是慌张地擦了擦眼镜?如果真这样,别担心,你没看错。这种定义变量的方法是和dynamic_cast同时增加到C++语言中的。这一特性使得写出的代码更简洁,因为对psa或pca来说,它们只有在被dynamic_cast成功初始化的情况下,才会真正被用到;使用新的语法,就不必在(包含转换的)条件语句外定义这些变量。(条款32解释了为什么通常要避免多余的变量定义)如果编译器尚不支持这种定义变量的新方法,可以按老方法来做:</P>
<P>for (list<BankAccount*>::iterator p =
allAccounts.begin();<BR> p !=
allAccounts.end();<BR> ++p) {</P>
<P> SavingsAccount *psa; //
传统定义<BR> CheckingAccount *pca; //
传统定义</P>
<P> if (psa = dynamic_cast<SavingsAccount*>(*p))
{<BR> psa->creditInterest();<BR> }</P>
<P> else if (pca = dynamic_cast<CheckingAccount*>(*p))
{<BR> pca->creditInterest();<BR> }</P>
<P> else {<BR> error("Unknown account type!");<BR>
}<BR>}</P>
<P>当然,从处理事情的重要性来说,把psa和pca这样的变量放在哪儿定义并不十分重要。重要之处在于:用if-then-else风格的编程来进行向下转换比用虚函数要逊色得多,应该将这种方法保留到万不得已的情况下使用。运气好的话,你的程序世界里将永远看不到这样悲惨荒凉的景象。</P><BR><BR></DIV></DIV></DIV><BR><BR>
<SCRIPT src="Effective C++ 2e Item39.files/get_readnum.htm"></SCRIPT>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TH id=white bgColor=#990000><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 cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TH id=white bgColor=#990000><FONT
color=#ffffff>发表评论</FONT></TH></TR></TBODY></TABLE>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#ffffff
border=0>
<TBODY>
<TR>
<TD>
<FORM name=add_critique action=/develop/add_critique.asp
method=post><INPUT type=hidden value=add name=critique_add> <INPUT
type=hidden value=9336 name=from> 评论人: <INPUT name=csdnname>
密码: <INPUT type=password name=csdnpassword>
评论:<BR> <TEXTAREA name=critique_content rows=8 cols=100></TEXTAREA><BR>
<INPUT onclick=javascript:submit1(); type=button value=发表评论 name=ubmit>
<INPUT type=hidden value=9336 name=id> </FORM></TD></TR></TBODY></TABLE>
<TABLE width=770 border=0>
<TBODY>
<TR>
<TD>
<TABLE cellPadding=2 width=770 border=0>
<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 src="http://www.csdn.net/job/images/csdn_job.gif"
border=0></A> </TD>
<TD align=middle width=510>
<OBJECT id=Movie1
codeBase=http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0
height=60 width=468
classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000><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
src="http://www.csdn.net/images/biaoshi.gif" border=0></A>
</TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD>
<TABLE height=20 cellSpacing=0 cellPadding=0 width=770 align=default
bgColor=#1f60a0 border=0>
<TBODY>
<TR class=font13px vAlign=center align=middle>
<TD class=font13px vAlign=center width=90 height=2></TD>
<TD width=2 rowSpan=2><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></TD>
<TD class=font13px width=90 height=2></TD>
<TD width=3 rowSpan=2><FONT color=#ffffff><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></FONT></TD>
<TD class=font13px width=90 height=2></TD>
<TD width=2 rowSpan=2><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></TD>
<TD class=font13px width=90 height=2></TD>
<TD width=3 rowSpan=2><FONT color=#ffffff><IMG height=13
src="http://www.csdn.net/images/ad4.gif" width=2></FONT></TD>
<TD width=350 height=2><FONT color=#ffffff></FONT></TD>
<TD width=10 rowSpan=2><FONT color=#ffffff><IMG height=11
src="http://www.csdn.net/images/ad3.gif" width=6></FONT></TD>
<TD class=font13px width=60 height=2></TD></TR>
<TR class=font14px vAlign=center align=middle>
<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 + -