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

📄 dynamiccast.html

📁 关于 C++ 的历史无须我来介绍了
💻 HTML
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>



  
  
  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">



  
  
  
  <link rel="stylesheet" href="css/print.css" type="text/css">



  
  
  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">



  
  
  
  <title>使用 dynamic_cast</title>
</head>


<body>



<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>



<h1><a href="CppGossip.html">C++
Gossip:&nbsp;使用 dynamic_cast</a></h1>



您可以使用static_cast(甚至是传统的C转型方式)将基底类别指标转换为衍生类别指标,这种转型方式是强制转型,在执行时期使用强制转型有危险性,因为编译器无法得知转型是否正确,执行时期真正指向的物件型态是未知的,透过简单的检查是避免错误的一种方式:<br>


<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">if(typeid(*base) == typeid(Derived1)) {</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">


<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; Derived1 *derived1 = static_cast&lt;Derived1*&gt;(base);</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">


<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; derived1-&gt;showOne();</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">


<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">}</span><br>


</div>



<br>



为了支援执行时期的型态转换动作,C++提供了dynamic_cast用来将一个基底类别的指标转型至衍生类别指标,称之为“安全向下转型”(Safe downcasting),它在执行时期进行型态转换动作,首先会确定转换目标与来源是否属同一个类别阶
层,接着才真正进行转换的动作,检验动作在执行时期完成,如果是一个指标,则转换成功时传回位址,失败的话会传回0,如果是参考的话,转换失败会丢出
bad_cast例外。<br>


<br>


可以将 <a href="RTTI.html">执行时期型态资讯(RTTI)</a> 中的showWho()函式如下修改:<br>


<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">void showWho(Base *base) {</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; base-&gt;foo();</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; if(Derived1 *derived1 = dynamic_cast&lt;Derived1*&gt;(base)) {</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; derived1-&gt;showOne();</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; }</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; else if(Derived2 *derived2 = static_cast&lt;Derived2*&gt;(base)) {</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; derived2-&gt;showTwo();&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">

<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">}</span><br>

</div>


<br>


由于dynamic_cast转换失败的话会传回0,因而运算的结果不可使用,必须先行对转换结果作检查才可以,如上例所示。<br>

<br>

如果使用参考的话,dynamic_cast在转换失败之后会丢出bad_cast例外,所以您必须使用try...catch来处理例外,例如:<br>

<br>



<pre>#include &lt;iostream&gt; <br>#include &lt;typeinfo&gt; <br>using namespace std; <br><br>class Base { <br>public: <br>    virtual void foo() = 0;<br>}; <br><br>class Derived1 : public Base { <br>public: <br>    void foo() { <br>        cout &lt;&lt; "Derived1" &lt;&lt; endl; <br>    } <br>    <br>    void showOne() {<br>         cout &lt;&lt; "Yes! It's Derived1." &lt;&lt; endl;<br>    }<br>}; <br><br>class Derived2 : public Base { <br>public: <br>    void foo() { <br>        cout &lt;&lt; "Derived2" &lt;&lt; endl; <br>    } <br>    <br>    void showTwo() {<br>         cout &lt;&lt; "Yes! It's Derived2." &lt;&lt; endl;<br>    }<br>}; <br><br>void showWho(Base &amp;base) {<br>    try {<br>        Derived1 derived1 = dynamic_cast&lt;Derived1&amp;&gt;(base);<br>        derived1.showOne();<br>    }<br>    catch(bad_cast) {<br>        cout &lt;&lt; "bad_cast 转型失败" &lt;&lt; endl;<br>    }<br><br>}<br><br>int main() { <br>    Derived1 derived1;<br>    Derived2 derived2; <br><br>    showWho(derived1);<br>    showWho(derived2);<br>&nbsp;<br>    return 0;<br>}</pre>





<span class="postbody"><br>

执行结果:</span><br>



<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">



  <tbody>



    <tr>



      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">Yes! It's Derived1.<br>

bad_cast 转型失败</span></small><span style="color: rgb(255, 255, 255);"><br>



      </span></td>



    </tr>



  
  
  
  </tbody>
</table>



<br>

<br>

<br>

<br>



</body>
</html>

⌨️ 快捷键说明

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