📄 effective c++ 2e item21.htm
字号:
constness”限制就被解除:</P>
<P>class String {<BR>public:</P>
<P> ... // same as above</P>
<P>private:<BR> char *data;</P>
<P> mutable size_t dataLength; //
这些数据成员现在<BR>
// 为mutable;他们可以在<BR> mutable bool lengthIsValid;
//
任何地方被修改,即使<BR>
// 在const成员函数里<BR>}; </P>
<P>size_t String::length() const<BR>{<BR> if (!lengthIsValid)
{<BR> dataLength = strlen(data); //
现在合法<BR> lengthIsValid =
true; // 同样合法<BR> }</P>
<P> return dataLength;<BR>}</P>
<P>mutable在处理“bitwise-constness限制”问题时是一个很好的方案,但它被加入到C++标准中的时间不长,所以有的编译器可能还不支持它。如果是这样,就不得不倒退到C++黑暗的旧时代去,在那儿,生活很简陋,const有时可能会被抛弃。</P>
<P>类C的一个成员函数中,this指针就好象经过如下的声明:</P>
<P>C * const
this;
// 非const成员函数中</P>
<P>const C * const this; //
const成员函数中</P>
<P>这种情况下(即编译器不支持mutable的情况下),如果想使那个有问题的String::length版本对const和非const对象都合法,就只有把this的类型从const
C * const改成C *
const。不能直接这么做,但可以通过初始化一个局部变量指针,使之指向this所指的同一个对象来间接实现。然后,就可以通过这个局部指针来访问你想修改的成员:</P>
<P>size_t String::length() const<BR>{<BR> // 定义一个不指向const对象的<BR> //
局部版本的this指针<BR> String * const localThis =<BR>
const_cast<String * const>(this);</P>
<P> if (!lengthIsValid) {<BR> localThis->dataLength =
strlen(data);<BR> localThis->lengthIsValid =
true;<BR> }</P>
<P> return dataLength;<BR>}</P>
<P>做的不是很漂亮。但为了完成想要的功能也就只有这么做。</P>
<P>当然,如果不能保证这个方法一定可行,就不要这么做:比如,一些老的“消除const”的方法就不行。特别是,如果this所指的对象真的是const,即,在定义时被声明为const,那么,“消除const”就会导致不可确定的后果。所以,如果想在成员函数中通过转换消除const,就最好先确信你要转换的对象最初没有被定义为const。</P>
<P>还有一种情况下,通过类型转换消除const会既有用又安全。这就是:将一个const对象传递到一个取非const参数的函数中,同时你又知道参数不会在函数内部被修改的情况时。第二个条件很重要,因为对一个只会被读的对象(不会被写)消除const永远是安全的,即使那个对象最初曾被定义为const。</P>
<P>例如,已经知道有些库不正确地声明了象下面这样的strlen函数:</P>
<P>size_t strlen(char *s);</P>
<P>strlen当然不会去修改s所指的数据——至少我一辈子没看见过。但因为有了这个声明,对一个const char
*类型的指针调用这个函数时就会不合法。为解决这个问题,可以在给strlen传参数时安全地把这个指针的const强制转换掉:</P>
<P>const char *klingonGreeting = "nuqneH"; //
"nuqneH"即"Hello"<BR>
// <BR>size_t length =<BR>
strlen(const_cast<char*>(klingonGreeting));</P>
<P>但不要滥用这个方法。只有在被调用的函数(比如本例中的strlen)不会修改它的参数所指的数据时,才能保证它可以正常工作。</P><BR><BR></DIV></DIV></DIV><BR><BR>
<SCRIPT src="Effective C++ 2e Item21.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=8815> 评论人: <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=8815> </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 + -