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

📄 chap09.htm

📁 This is the second part of that lab manual to teach you how to make real-time programme and how to d
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<font color=#009900>// Counting shapes</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include <font color=#004488>"..</font><font color=#004488>/purge.h"</font>
#include &lt;iostream&gt;
#include &lt;ctime&gt;
#include &lt;typeinfo&gt;
#include &lt;vector&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>class</font> Shape {
<font color=#0000ff>protected</font>:
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> count;
<font color=#0000ff>public</font>:
  Shape() { count++; }
  <font color=#0000ff>virtual</font> ~Shape() { count--; }
  <font color=#0000ff>virtual</font> <font color=#0000ff>void</font> draw() <font color=#0000ff>const</font> = 0;
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> quantity() { <font color=#0000ff>return</font> count; }
};

<font color=#0000ff>int</font> Shape::count = 0;

<font color=#0000ff>class</font> SRectangle : <font color=#0000ff>public</font> Shape {
  <font color=#0000ff>void</font> <font color=#0000ff>operator</font>=(SRectangle&amp;); <font color=#009900>// Disallow</font>
<font color=#0000ff>protected</font>:
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> count;
<font color=#0000ff>public</font>:
  SRectangle() { count++; }
  SRectangle(<font color=#0000ff>const</font> SRectangle&amp;) { count++;}
  ~SRectangle() { count--; }
  <font color=#0000ff>void</font> draw() <font color=#0000ff>const</font> {
    cout &lt;&lt; <font color=#004488>"SRectangle::draw()"</font> &lt;&lt; endl;
  }
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> quantity() { <font color=#0000ff>return</font> count; }
};

<font color=#0000ff>int</font> SRectangle::count = 0;

<font color=#0000ff>class</font> SEllipse : <font color=#0000ff>public</font> Shape {
  <font color=#0000ff>void</font> <font color=#0000ff>operator</font>=(SEllipse&amp;); <font color=#009900>// Disallow</font>
<font color=#0000ff>protected</font>:
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> count;
<font color=#0000ff>public</font>:
  SEllipse() { count++; }
  SEllipse(<font color=#0000ff>const</font> SEllipse&amp;) { count++; }
  ~SEllipse() { count--; }
  <font color=#0000ff>void</font> draw() <font color=#0000ff>const</font> {
    cout &lt;&lt; <font color=#004488>"SEllipse::draw()"</font> &lt;&lt; endl;
  }
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> quantity() { <font color=#0000ff>return</font> count; }
};

<font color=#0000ff>int</font> SEllipse::count = 0;

<font color=#0000ff>class</font> SCircle : <font color=#0000ff>public</font> SEllipse {
  <font color=#0000ff>void</font> <font color=#0000ff>operator</font>=(SCircle&amp;); <font color=#009900>// Disallow</font>
<font color=#0000ff>protected</font>:
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> count;
<font color=#0000ff>public</font>:
  SCircle() { count++; }
  SCircle(<font color=#0000ff>const</font> SCircle&amp;) { count++; }
  ~SCircle() { count--; }
  <font color=#0000ff>void</font> draw() <font color=#0000ff>const</font> {
    cout &lt;&lt; <font color=#004488>"SCircle::draw()"</font> &lt;&lt; endl;
  }
  <font color=#0000ff>static</font> <font color=#0000ff>int</font> quantity() { <font color=#0000ff>return</font> count; }
};

<font color=#0000ff>int</font> SCircle::count = 0;

<font color=#0000ff>int</font> main() {
  vector&lt;Shape*&gt; shapes;
  srand(time(0)); <font color=#009900>// Seed random number generator</font>
  <font color=#0000ff>const</font> <font color=#0000ff>int</font> mod = 12;
  <font color=#009900>// Create a random quantity of each type:</font>
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; rand() % mod; i++)
    shapes.push_back(<font color=#0000ff>new</font> SRectangle);
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j &lt; rand() % mod; j++)
    shapes.push_back(<font color=#0000ff>new</font> SEllipse);
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> k = 0; k &lt; rand() % mod; k++)
    shapes.push_back(<font color=#0000ff>new</font> SCircle);
  <font color=#0000ff>int</font> nCircles = 0;
  <font color=#0000ff>int</font> nEllipses = 0;
  <font color=#0000ff>int</font> nRects = 0;
  <font color=#0000ff>int</font> nShapes = 0;
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> u = 0; u &lt; shapes.size(); u++) {
    shapes[u]-&gt;draw();
    <font color=#0000ff>if</font>(<font color=#0000ff>dynamic_cast</font>&lt;SCircle*&gt;(shapes[u]))
      nCircles++;
    <font color=#0000ff>if</font>(<font color=#0000ff>dynamic_cast</font>&lt;SEllipse*&gt;(shapes[u]))
      nEllipses++;
    <font color=#0000ff>if</font>(<font color=#0000ff>dynamic_cast</font>&lt;SRectangle*&gt;(shapes[u]))
      nRects++;
    <font color=#0000ff>if</font>(<font color=#0000ff>dynamic_cast</font>&lt;Shape*&gt;(shapes[u]))
      nShapes++;
  }
  cout &lt;&lt; endl &lt;&lt; endl
    &lt;&lt; <font color=#004488>"Circles = "</font> &lt;&lt; nCircles &lt;&lt; endl
    &lt;&lt; <font color=#004488>"Ellipses = "</font> &lt;&lt; nEllipses &lt;&lt; endl
    &lt;&lt; <font color=#004488>"Rectangles = "</font> &lt;&lt; nRects &lt;&lt; endl
    &lt;&lt; <font color=#004488>"Shapes = "</font> &lt;&lt; nShapes &lt;&lt; endl
    &lt;&lt; endl
    &lt;&lt; <font color=#004488>"SCircle::quantity() = "</font>
    &lt;&lt; SCircle::quantity() &lt;&lt; endl
    &lt;&lt; <font color=#004488>"SEllipse::quantity() = "</font>
    &lt;&lt; SEllipse::quantity() &lt;&lt; endl
    &lt;&lt; <font color=#004488>"SRectangle::quantity() = "</font>
    &lt;&lt; SRectangle::quantity() &lt;&lt; endl
    &lt;&lt; <font color=#004488>"Shape::quantity() = "</font>
    &lt;&lt; Shape::quantity() &lt;&lt; endl;
  purge(shapes);
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Both types work for this example, but the
<B>static</B> member approach can be used only if you own the code and have
installed the <B>static</B> members and functions (or if a vendor provides them
for you). In addition, the syntax for RTTI may then be different from one class
to
another.</FONT><A NAME="_Toc312374136"></A><A NAME="_Toc519042084"></A><BR></P></DIV>
<A NAME="Heading291"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H2 ALIGN="LEFT">
Syntax specifics</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This section looks at the details of how
the two forms of RTTI work, and how they
differ.</FONT><A NAME="_Toc312374137"></A><A NAME="_Toc519042085"></A><BR></P></DIV>
<A NAME="Heading292"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
typeid(&#160;) with built-in types</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For consistency, the
<B>typeid(&#160;)<A NAME="Index530"></A><A NAME="Index531"></A><A NAME="Index532"></A></B>
operator works with built-in types. So the following expressions are
true:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C09:TypeidAndBuiltins.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include &lt;cassert&gt;
#include &lt;typeinfo&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>int</font> main() {
  assert(<font color=#0000ff>typeid</font>(47) == <font color=#0000ff>typeid</font>(<font color=#0000ff>int</font>));
  assert(<font color=#0000ff>typeid</font>(0) == <font color=#0000ff>typeid</font>(<font color=#0000ff>int</font>));
  <font color=#0000ff>int</font> i;
  assert(<font color=#0000ff>typeid</font>(i) == <font color=#0000ff>typeid</font>(<font color=#0000ff>int</font>));
  assert(<font color=#0000ff>typeid</font>(&amp;i) == <font color=#0000ff>typeid</font>(<font color=#0000ff>int</font>*));
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><DIV ALIGN="LEFT"><P><A NAME="_Toc312374138"></A><A NAME="_Toc519042086"></A><BR></P></DIV>
<A NAME="Heading293"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Producing the proper type name</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>typeid(&#160;)</B> must work properly
in all situations. For example, the following class contains a nested
class<A NAME="Index533"></A><A NAME="Index534"></A>:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C09:RTTIandNesting.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include &lt;iostream&gt;
#include &lt;typeinfo&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>class</font> One {
  <font color=#0000ff>class</font> Nested {};
  Nested* n;
<font color=#0000ff>public</font>:
  One() : n(<font color=#0000ff>new</font> Nested) {}
  ~One() { <font color=#0000ff>delete</font> n; }
  Nested* nested() { <font color=#0000ff>return</font> n; }
};

<font color=#0000ff>int</font> main() {
  One o;
  cout &lt;&lt; <font color=#0000ff>typeid</font>(*o.nested()).name() &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>typeinfo::name(&#160;)</B> member
function will still produce the proper class name; the result is
<B>One::Nested</B>.</FONT><A NAME="_Toc312374139"></A><A NAME="_Toc519042087"></A><BR></P></DIV>
<A NAME="Heading294"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Nonpolymorphic
types<BR><A NAME="Index535"></A><A NAME="Index536"></A><A NAME="Index537"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Although <B>typeid(&#160;)</B> works with
nonpolymorphic types (those that don&#8217;t have a virtual function in the base
class), the information you get this way is dubious. For the following class
hierarchy,</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C09:RTTIWithoutPolymorphism.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test</font>
#include &lt;cassert&gt;
#include &lt;typeinfo&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>class</font> X {
 <font color=#0000ff>int</font> i; 
<font color=#0000ff>public</font>:
  <font color=#009900>// ...</font>
};

<font color=#0000ff>class</font> Y : <font color=#0000ff>public</font> X { 
  <font color=#0000ff>int</font> j;
<font color=#0000ff>public</font>:
  <font color=#009900>// ...</font>
};

<font color=#0000ff>int</font> main() {
  X* xp = <font color=#0000ff>new</font> Y;
  assert(<font color=#0000ff>typeid</font>(*xp) == <font color=#0000ff>typeid</font>(X));
  assert(<font color=#0000ff>typeid</font>(*xp) != <font color=#0000ff>typeid</font>(Y));
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you create an object of the derived
type and upcast it,</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>X* xp = <font color=#0000ff>new</font> Y;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>typeid(&#160;)</B> operator will
produce results, but not the ones you might expect. Because there&#8217;s no
polymorphism, the static type information is used:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>typeid</font>(*xp) == <font color=#0000ff>typeid</font>(X)
<font color=#0000ff>typeid</font>(*xp) != <font color=#0000ff>typeid</font>(Y)</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">RTTI is intended for use only with
polymorphic
classes.</FONT><A NAME="_Toc312374140"></A><A NAME="_Toc519042088"></A><BR></P></DIV>
<A NAME="Heading295"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Casting to intermediate
levels<BR><A NAME="Index538"></A><A NAME="Index539"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>dynamic_cast</B> can detect both exact
types and, in an inheritance hierarchy with multiple levels, intermediate types.

⌨️ 快捷键说明

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