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

📄 mc1.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
📖 第 1 页 / 共 4 页
字号:
</UL><A NAME="77187"></A>
<A NAME="dingp26"></A>you should now generally write like this:<SCRIPT>create_link(26);</SCRIPT>

<A NAME="77188"></A>
<UL><PRE>static_cast&lt;<I>type</I>&gt;(<I>expression</I>)
</PRE>
</UL><A NAME="77189"></A>
<P><A NAME="dingp27"></A>
For example, suppose you'd like to cast an <CODE>int</CODE> to a <CODE>double</CODE> to force an expression involving <CODE>int</CODE>s to yield a floating point value. Using C-style casts, you could do it like <NOBR>this:<SCRIPT>create_link(27);</SCRIPT>
</NOBR></P><A NAME="77190"></A>
<UL><PRE>int firstNumber, secondNumber;
<A NAME="78576"></A>
...
<A NAME="78575"></A>
double result = ((double)firstNumber)/secondNumber;</PRE>
</UL><A NAME="78788"></A>
<P><A NAME="dingp28"></A>With the new casts, you'd write it this <NOBR>way:<SCRIPT>create_link(28);</SCRIPT>
</NOBR></p>
<A NAME="78789"></A>
<UL><PRE>double result = static_cast&lt;double&gt;(firstNumber)/secondNumber;</PRE>
</UL>
<A NAME="78790"></A>
<A NAME="p13"></A><p><A NAME="dingp29"></A>Now <I>there's</I> a cast that's easy to see, both for humans and for <NOBR>programs.<SCRIPT>create_link(29);</SCRIPT>
</NOBR></P><A NAME="77196"></A>
<P><A NAME="dingp30"></A>
<CODE>static_cast</CODE> has basically the same power and meaning as the general-purpose C-style cast. It also has the same kind of restrictions. For example, you can't cast a <CODE>struct</CODE> into an <CODE>int</CODE> or a <CODE>double</CODE> into a pointer using <CODE>static_cast</CODE> any more than you can with a C-style cast. Furthermore, <CODE>static_cast</CODE> can't remove <CODE>const</CODE>ness from an expression, because another new cast, <CODE>const_cast</CODE>, is designed specifically to do <NOBR>that.<SCRIPT>create_link(30);</SCRIPT>
</NOBR></P><A NAME="81192"></A>
<P><A NAME="dingp31"></A>
The other new C++ casts are used for more restricted purposes. <CODE>const_cast</CODE> is used to cast away the <CODE>const</CODE>ness or <CODE>volatile</CODE>ness of an expression. By using a <CODE>const_cast</CODE>, you emphasize (to both humans and compilers) that the only thing you want to change through the cast is the <CODE>const</CODE>ness or <CODE>volatile</CODE>ness of something. This meaning is enforced by compilers. If you try to employ <CODE>const_cast</CODE> for anything other than modifying the <CODE>const</CODE>ness or <CODE>volatile</CODE>ness of an expression, your cast will be rejected. Here are some <NOBR>examples:<SCRIPT>create_link(31);</SCRIPT>
</NOBR></P><A NAME="78221"></A>
<UL><PRE>class Widget { ... };
class SpecialWidget: public Widget { ... };
</PRE>
</UL><A NAME="78225"></A>
<UL><PRE>void update(SpecialWidget *psw);
</PRE>
</UL><A NAME="78295"></A>
<UL><PRE>SpecialWidget sw;                       // sw is a non-const object,
const SpecialWidget&amp; csw = sw;          // but csw is a reference to
                                        // it as a const object
						 <A NAME="78296"></A>
update(&amp;csw);            // error! can't pass a const
                         // SpecialWidget* to a function
                         // taking a SpecialWidget*
						 <A NAME="78297"></A>
update(const_cast&lt;SpecialWidget*&gt;(&amp;csw));
                         // fine, the constness of &amp;csw is
                         // explicitly cast away (and
                         // csw &#151; and sw &#151; may now be
                         // changed inside update)
						 <A NAME="78312"></A>
update((SpecialWidget*)&amp;csw);
                         // same as above, but using a
                         // harder-to-recognize C-style cast
						 <A NAME="78313"></A>
Widget *pw = new SpecialWidget;
<A NAME="78320"></A>
update(pw);              // error! pw's type is Widget*, but
                         // update takes a SpecialWidget*
<A NAME="78326"></A>
update(const_cast&lt;SpecialWidget*&gt;(pw));
                         // error! const_cast can be used only
                         // to affect constness or volatileness,
                         // never to cast down the inheritance
                         // hierarch
</PRE>
</UL>
<A NAME="78335"></A>
<P><A NAME="dingp32"></A>
By far the most common use of <CODE>const_cast</CODE> is to cast away the <CODE>const</CODE>ness of an <NOBR>object.<SCRIPT>create_link(32);</SCRIPT>
</NOBR></P><A NAME="78401"></A>
<A NAME="p14"></A><P><A NAME="dingp33"></A>
The second specialized type of cast, <CODE>dynamic_cast</CODE>, is used to perform <I>safe casts</I> down or across an inheritance hierarchy. That is, you use <CODE>dynamic_cast</CODE> to cast pointers or references to base class objects into pointers or references to derived or sibling base class objects in such a way that you can determine whether the casts succeeded.<A HREF="#79079" onMouseOver = "self.status = 'Link to Footnote 1'; return true" onMouseOut = "self.status = self.defaultStatus"><sup>1</sup></A> Failed casts are indicated by a null pointer (when casting pointers) or an exception (when casting <NOBR>references):<SCRIPT>create_link(33);</SCRIPT>
</NOBR></P>
<A NAME="78385"></A>
<UL><PRE>Widget *pw;
</PRE>
</UL><A NAME="78391"></A>
<UL><PRE>...
</PRE>
</UL><A NAME="78390"></A>
<UL><PRE>update(dynamic_cast&lt;SpecialWidget*&gt;(pw));
                         // fine, passes to update a pointer
                         // to the SpecialWidget pw points to
                         // if pw really points to one,
                         // otherwise passes the null pointer
</PRE>
</UL><A NAME="78423"></A>
<UL><PRE>void updateViaRef(SpecialWidget&amp; rsw);
</PRE>
</UL><A NAME="78870"></A>
<UL><PRE>updateViaRef(dynamic_cast&lt;SpecialWidget&amp;&gt;(*pw));
                         // fine, passes to updateViaRef the
                         // SpecialWidget pw points to if pw
                         // really points to one, otherwise
                         // throws an exception
</PRE>
</UL><A NAME="79012"></A>
<P><A NAME="dingp34"></A>
<CODE>dynamic_cast</CODE>s are restricted to helping you navigate inheritance hierarchies. They cannot be applied to types lacking virtual functions (see also <A HREF="./MC4_FR.HTM#41284" TARGET="_top" onMouseOver = "self.status = 'Link to MEC++ Item 24'; return true" onMouseOut = "self.status = self.defaultStatus">Item 24</A>), nor can they cast away <CODE>const</CODE>ness:<SCRIPT>create_link(34);</SCRIPT>
</P><A NAME="78958"></A>
<UL><PRE>int firstNumber, secondNumber;
...
double result = dynamic_cast&lt;double&gt;(firstNumber)/secondNumber;
                         // error! no inheritance is involved
</PRE>
</UL><A NAME="78967"></A>
<UL><PRE>const SpecialWidget sw;
...
update(dynamic_cast&lt;SpecialWidget*&gt;(&amp;sw));
                         // error! dynamic_cast can't cast
                         // away constness
</PRE>
</UL><A NAME="78774"></A>
<P><A NAME="dingp35"></A>
If you want to perform a cast on a type where inheritance is not involved, you probably want a <CODE>static_cast</CODE>. To cast <CODE>const</CODE>ness away, you always want a <CODE>const_cast</CODE>.<SCRIPT>create_link(35);</SCRIPT>
</P><A NAME="79074"></A>
<P><A NAME="dingp36"></A>
The last of the four new casting forms is <CODE>reinterpret_cast</CODE>. This operator is used to perform type conversions whose result is nearly always implementation-defined. As a result, <CODE>reinterpret_cast</CODE>s are rarely <NOBR>portable.<SCRIPT>create_link(36);</SCRIPT>
</NOBR></P><A NAME="78457"></A>
<A NAME="p15"></A><P><A NAME="dingp37"></A>
The most common use of <CODE>reinterpret_cast</CODE> is to cast between function pointer types. For example, suppose you have an array of pointers to functions of a particular <NOBR>type:<SCRIPT>create_link(37);</SCRIPT>
</NOBR></P><A NAME="78458"></A>
<UL><PRE>typedef void (*FuncPtr)();         // a FuncPtr is a pointer
                                   // to a function taking no
                                   // args and returning void
</PRE>
</UL><A NAME="78459"></A>
<UL><PRE>FuncPtr funcPtrArray[10];          // funcPtrArray is an array
                                   // of 10 FuncPtrs
</PRE>
</UL><A NAME="78460"></A>
<P><A NAME="dingp38"></A>
Let us suppose you wish (for some unfathomable reason) to place a pointer to the following function into <CODE>funcPtrArray</CODE>:<SCRIPT>create_link(38);</SCRIPT>
</P><A NAME="78461"></A>
<UL><PRE>int doSomething();
</PRE>
</UL><A NAME="78475"></A>
<P><A NAME="dingp39"></A>
You can't do what you want without a cast, because <CODE>doSomething</CODE> has the wrong type for <CODE>funcPtrArray</CODE>. The functions in <CODE>funcPtrArray</CODE> return <CODE>void</CODE>, but <CODE>doSomething</CODE> returns an <CODE>int</CODE>:<SCRIPT>create_link(39);</SCRIPT>
</P><A NAME="78479"></A>
<UL><PRE>funcPtrArray[0] = &amp;doSomething;     // error! type mismatch
</PRE>
</UL><A NAME="78481"></A>
<P><A NAME="dingp40"></A>
A <CODE>reinterpret_cast</CODE> lets you force compilers to see things your <NOBR>way:<SCRIPT>create_link(40);</SCRIPT>
</NOBR></P><A NAME="78486"></A>
<UL><PRE>funcPtrArray[0] =                   // this compiles
  reinterpret_cast&lt;FuncPtr&gt;(&amp;doSomething);
</PRE>
</UL><A NAME="78437"></A>
<P><A NAME="dingp41"></A>
Casting function pointers is not portable (C++ offers no guarantee that all function pointers are represented the same way), and in some cases such casts yield incorrect results (see <A HREF="./MC5_FR.HTM#34883" TARGET="_top" onMouseOver = "self.status = 'Link to MEC++ Item 31'; return true" onMouseOut = "self.status = self.defaultStatus">Item 31</A>), so you should avoid casting function pointers unless your back's to the wall and a knife's at your throat. A sharp knife. A <I>very</I> sharp <NOBR>knife.<SCRIPT>create_link(41);</SCRIPT>
</NOBR></P><A NAME="77203"></A>
<P><A NAME="dingp42"></A>
If your compilers lack support for the new casting forms, you can use traditional casts in place of <CODE>static_cast</CODE>, <CODE>const_cast</CODE>, and <CODE>reinterpret_cast</CODE>. Furthermore, you can use macros to approximate the new <NOBR>syntax:<SCRIPT>create_link(42);</SCRIPT>
</NOBR></P><A NAME="78698"></A>
<UL><PRE>#define static_cast(TYPE,EXPR)       ((TYPE)(EXPR))
#define const_cast(TYPE,EXPR)        ((TYPE)(EXPR))
#define reinterpret_cast(TYPE,EXPR)  ((TYPE)(EXPR))
</PRE>
</UL><A NAME="78719"></A>
<P><A NAME="dingp43"></A>
You'd use the approximations like <NOBR>this:<SCRIPT>create_link(43);</SCRIPT>
</NOBR></P><A NAME="78727"></A>
<UL><PRE>double result = static_cast(double, firstNumber)/secondNumber;
</PRE>
</UL><A NAME="78707"></A>
<UL><PRE>update(const_cast(SpecialWidget*, &amp;sw));
</PRE>
</UL><A NAME="78735"></A>
<UL><PRE>funcPtrArray[0] = reinterpret_cast(FuncPtr, &amp;doSomething);
</PRE>

⌨️ 快捷键说明

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