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

📄 item_094.htm

📁 C++程序编写规范,适合C++中级读者
💻 HTM
📖 第 1 页 / 共 2 页
字号:
"Times New Roman"'>摘要</span></b></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>即使是撒小谎,有些也会让你受到惩罚:强制去除</span><span
lang=EN-US>const</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>有时会导致未定义的结果,即使是合法的,这也是拙劣的编程风格的一种主要成份。</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>讨论</span></b></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>一旦用了</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>,就绝不(应该)再回头。如果一个对象原先确实定义为</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>,那么强制去除</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>将使所有的假设失效并导致未定义的行为。例如,编译器可以(也的确是这样做的)将常量数据放在只读存储器(</span><span
lang=EN-US>ROM</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>)中或受到写保护的内存页(</span><span lang=EN-US>RAM
pages</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>)中,强制去除此类真正的</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>对象的</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>限定符是一种欺骗行为,应该受到惩罚,它经常表现为内存故障。</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>即使强制去除</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>不会导致程序崩溃,它仍然毁坏了承诺,并且不会表现得如很多人预期地那样。例如,下面的代码不会分配一个大小可变的数组:</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='margin-left:36.0pt'><span class=GramE><span
lang=EN-US>void</span></span><span lang=EN-US> Foolish( unsigned <span
class=SpellE>int</span> n ) {</span></p>

<p class=MsoNormal style='margin-left:36.0pt'><span lang=EN-US><span
style='mso-spacerun:yes'>&nbsp; </span><span class=GramE>const</span> unsigned <span
class=SpellE>int</span> size = 1;</span></p>

<p class=MsoNormal style='margin-left:36.0pt;tab-stops:252.0pt'><span
lang=EN-US><span style='mso-spacerun:yes'>&nbsp; </span><span class=SpellE>const_cast</span>&lt;unsigned
<span class=SpellE>int</span>&amp;&gt;(size) = n;<span style='mso-tab-count:
1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><i
style='mso-bidi-font-style:normal'>// </i></span><i style='mso-bidi-font-style:
normal'><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>糟糕:别这样做</span></i></p>

<p class=MsoNormal style='margin-left:36.0pt;tab-stops:252.0pt'><span
lang=EN-US><span style='mso-spacerun:yes'>&nbsp; </span>char buffer[size];<span
style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><i
style='mso-bidi-font-style:normal'>// </i></span><i style='mso-bidi-font-style:
normal'><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>分配的大小总是为</span><span lang=EN-US>1</span></i></p>

<p class=MsoNormal style='margin-left:36.0pt'><i style='mso-bidi-font-style:
normal'><span lang=EN-US><span style='mso-spacerun:yes'>&nbsp; </span>// ...<o:p></o:p></span></i></p>

<p class=MsoNormal style='margin-left:36.0pt'><span lang=EN-US>}</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span lang=EN-US>C++</span><span style='font-family:宋体;
mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:"Times New Roman"'>有一个隐式的</span><span
class=SpellE><span lang=EN-US>const_cast</span></span><span style='font-family:
宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:"Times New Roman"'>,用来把一个字符串“起死回生”为一个</span><span
lang=EN-US>char*</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>:</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='margin-left:36.0pt'><span class=GramE><span
lang=EN-US>char</span></span><span lang=EN-US>* weird = “Trick or treat?”;</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>编译器不声不响地用</span><span class=SpellE><span
lang=EN-US>const_cast</span></span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>把</span><span
lang=EN-US>const char[16]</span><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>强制转换为</span><span
lang=EN-US>char*</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>。允许这样做是为了保持与</span><span lang=EN-US>C
API</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>的兼容性,但这是</span><span lang=EN-US>C++</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>类型系统中的一个漏洞。字符串是可以放在</span><span lang=EN-US>ROM</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>中的,试图修改这样的字符串很有可能导致一个内存故障。</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>例外</span></b></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>为了调用</span><span lang=EN-US>const-incorrect
API</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>(参见第</span><span lang=EN-US>15</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>条),强制去除</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>可能是必要的。另外如果一个函数必须接收并返回一个相同类型的引用,该函数有重载的</span><span
lang=EN-US>const</span><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>和非</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>版本,且其中一个通过调用另一个来实现,那么强制去除</span><span lang=EN-US>const</span><span
style='font-family:宋体;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:
"Times New Roman"'>也是有用的:</span></p>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='margin-left:36.0pt'><span class=GramE><span
lang=EN-US>const</span></span><span lang=EN-US> Object&amp; f( const
Object&amp; );</span></p>

<p class=MsoNormal style='margin-left:36.0pt'><span lang=EN-US>Object&amp; <span
class=GramE>f(</span> Object&amp; <span class=SpellE>obj</span> ) {</span></p>

<p class=MsoNormal style='margin-left:36.0pt'><span lang=EN-US><span
style='mso-spacerun:yes'>&nbsp; </span>Const Object&amp; ref = <span
class=SpellE>obj</span>;</span></p>

<p class=MsoNormal style='margin-left:36.0pt;tab-stops:270.0pt'><span
lang=EN-US><span style='mso-spacerun:yes'>&nbsp; </span>return </span><span
class=SpellE><span lang=EN-US style='font-family:"Arial Black"'>const_cast</span></span><span
lang=EN-US style='font-family:"Arial Black"'>&lt;Object&amp;&gt;(</span><span
lang=EN-US> f(ref) </span><span lang=EN-US style='font-family:"Arial Black"'>)</span><span
lang=EN-US>;<span style='mso-tab-count:1'>&nbsp;&nbsp; </span><i
style='mso-bidi-font-style:normal'>// </i></span><i style='mso-bidi-font-style:
normal'><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>必须强制去除返回</span><span lang=EN-US><o:p></o:p></span></i></p>

<p class=MsoNormal style='margin-left:36.0pt;tab-stops:270.0pt'><span
lang=EN-US><span style='mso-tab-count:1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><i
style='mso-bidi-font-style:normal'>// </i></span><i style='mso-bidi-font-style:
normal'><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman"'>类型的</span><span lang=EN-US>const</span></i><i
style='mso-bidi-font-style:normal'><span style='font-family:宋体;mso-ascii-font-family:
"Times New Roman";mso-hansi-font-family:"Times New Roman"'>限定符</span></i></p>

<p class=MsoNormal style='margin-left:36.0pt'><span lang=EN-US>}</span></p>

</div>

</body>

</html>

⌨️ 快捷键说明

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