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

📄 chapter07.html

📁 《C++编程思想》中文版。。。。。。。。。。。。。
💻 HTML
📖 第 1 页 / 共 4 页
字号:
Overloading example</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">We can now modify earlier examples to use
function overloading. As stated before, an immediately useful place for
overloading is in constructors. You can see this in the following version of the
<B>Stash</B> class: <A NAME="Index1405"></A></FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C07:Stash3.h</font>
<font color=#009900>// Function overloading</font>
#ifndef STASH3_H
#define STASH3_H

<font color=#0000ff>class</font> Stash {
  <font color=#0000ff>int</font> size;      <font color=#009900>// Size of each space</font>
  <font color=#0000ff>int</font> quantity;  <font color=#009900>// Number of storage spaces</font>
  <font color=#0000ff>int</font> next;      <font color=#009900>// Next empty space</font>
  <font color=#009900>// Dynamically allocated array of bytes:</font>
  <font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>* storage;
  <font color=#0000ff>void</font> inflate(<font color=#0000ff>int</font> increase);
<font color=#0000ff>public</font>:
  Stash(<font color=#0000ff>int</font> size); <font color=#009900>// Zero quantity</font>
  Stash(<font color=#0000ff>int</font> size, <font color=#0000ff>int</font> initQuantity);
  ~Stash();
  <font color=#0000ff>int</font> add(<font color=#0000ff>void</font>* element);
  <font color=#0000ff>void</font>* fetch(<font color=#0000ff>int</font> index);
  <font color=#0000ff>int</font> count();
};
#endif <font color=#009900>// STASH3_H ///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first <B>Stash(&#160;)</B>
constructor is the same as before, but the second one has a <B>Quantity</B>
argument to indicate the initial number of storage places to be allocated. In
the definition, you can see that the internal value of <B>quantity</B> is set to
zero, along with the <B>storage</B> pointer. In the second constructor, the call
to <B>inflate(initQuantity)</B> increases <B>quantity</B> to the allocated
size:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C07:Stash3.cpp {O}</font>
<font color=#009900>// Function overloading</font>
#include <font color=#004488>"Stash3.h"</font>
#include <font color=#004488>"../require.h"</font>
#include &lt;iostream&gt;
#include &lt;cassert&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;
<font color=#0000ff>const</font> <font color=#0000ff>int</font> increment = 100;

Stash::Stash(<font color=#0000ff>int</font> sz) {
  size = sz;
  quantity = 0;
  next = 0;
  storage = 0;
}

Stash::Stash(<font color=#0000ff>int</font> sz, <font color=#0000ff>int</font> initQuantity) {
  size = sz;
  quantity = 0;
  next = 0;
  storage = 0;
  inflate(initQuantity);
}

Stash::~Stash() {
  <font color=#0000ff>if</font>(storage != 0) {
    cout &lt;&lt; <font color=#004488>"freeing storage"</font> &lt;&lt; endl;
    <font color=#0000ff>delete</font> []storage;
  }
}

<font color=#0000ff>int</font> Stash::add(<font color=#0000ff>void</font>* element) {
  <font color=#0000ff>if</font>(next &gt;= quantity) <font color=#009900>// Enough space left?</font>
    inflate(increment);
  <font color=#009900>// Copy element into storage,</font>
  <font color=#009900>// starting at next empty space:</font>
  <font color=#0000ff>int</font> startBytes = next * size;
  <font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>* e = (<font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>*)element;
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; size; i++)
    storage[startBytes + i] = e[i];
  next++;
  <font color=#0000ff>return</font>(next - 1); <font color=#009900>// Index number</font>
}

<font color=#0000ff>void</font>* Stash::fetch(<font color=#0000ff>int</font> index) {
  require(0 &lt;= index, <font color=#004488>"Stash::fetch (-)index"</font>);
  <font color=#0000ff>if</font>(index &gt;= next)
    <font color=#0000ff>return</font> 0; <font color=#009900>// To indicate the end</font>
  <font color=#009900>// Produce pointer to desired element:</font>
  <font color=#0000ff>return</font> &amp;(storage[index * size]);
}

<font color=#0000ff>int</font> Stash::count() {
  <font color=#0000ff>return</font> next; <font color=#009900>// Number of elements in CStash</font>
}

<font color=#0000ff>void</font> Stash::inflate(<font color=#0000ff>int</font> increase) {
  assert(increase &gt;= 0);
  <font color=#0000ff>if</font>(increase == 0) <font color=#0000ff>return</font>;
  <font color=#0000ff>int</font> newQuantity = quantity + increase;
  <font color=#0000ff>int</font> newBytes = newQuantity * size;
  <font color=#0000ff>int</font> oldBytes = quantity * size;
  <font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>* b = <font color=#0000ff>new</font> <font color=#0000ff>unsigned</font> <font color=#0000ff>char</font>[newBytes];
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; oldBytes; i++)
    b[i] = storage[i]; <font color=#009900>// Copy old to new</font>
  <font color=#0000ff>delete</font> [](storage); <font color=#009900>// Release old storage</font>
  storage = b; <font color=#009900>// Point to new memory</font>
  quantity = newQuantity; <font color=#009900>// Adjust the size</font>
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When you use the first constructor no
memory is allocated for <B>storage</B>. The allocation happens the first time
you try to <B>add(&#160;)</B> an object and any time the current block of memory
is exceeded inside <B>add(&#160;)</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Both constructors are exercised in the
test program:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C07:Stash3Test.cpp</font>
<font color=#009900>//{L} Stash3</font>
<font color=#009900>// Function overloading</font>
#include <font color=#004488>"Stash3.h"</font>
#include <font color=#004488>"../require.h"</font>
#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>int</font> main() {
  Stash intStash(<font color=#0000ff>sizeof</font>(<font color=#0000ff>int</font>));
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 100; i++)
    intStash.add(&amp;i);
  <font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j &lt; intStash.count(); j++)
    cout &lt;&lt; <font color=#004488>"intStash.fetch("</font> &lt;&lt; j &lt;&lt; <font color=#004488>") = "</font>
         &lt;&lt; *(<font color=#0000ff>int</font>*)intStash.fetch(j)
         &lt;&lt; endl;
  <font color=#0000ff>const</font> <font color=#0000ff>int</font> bufsize = 80;
  Stash stringStash(<font color=#0000ff>sizeof</font>(<font color=#0000ff>char</font>) * bufsize, 100);
  ifstream in(<font color=#004488>"Stash3Test.cpp"</font>);
  assure(in, <font color=#004488>"Stash3Test.cpp"</font>);
  string line;
  <font color=#0000ff>while</font>(getline(in, line))
    stringStash.add((<font color=#0000ff>char</font>*)line.c_str());
  <font color=#0000ff>int</font> k = 0;
  <font color=#0000ff>char</font>* cp;
  <font color=#0000ff>while</font>((cp = (<font color=#0000ff>char</font>*)stringStash.fetch(k++))!=0)
    cout &lt;&lt; <font color=#004488>"stringStash.fetch("</font> &lt;&lt; k &lt;&lt; <font color=#004488>") = "</font>
         &lt;&lt; cp &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The constructor call for <B>stringStash
</B>uses a second argument; presumably you know something special about the
specific problem you&#8217;re solving that allows you to choose an initial size
for the <B>Stash</B>.</FONT><A NAME="_Toc472654870"></A><BR></P></DIV>
<A NAME="Heading241"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
unions<BR><A NAME="Index1406"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As you&#8217;ve seen, the only difference
between <B>struct </B>and <B>class </B>in C++ is that <B>struct </B>defaults to
<B>public </B>and <B>class </B>defaults to <B>private</B>. A <B>struct</B> can
also have constructors and destructors, as you might expect. But it turns out
that a <A NAME="Index1407"></A><B>union</B> can also have a constructor,
destructor, member functions, and even access control. You can again see the use
and benefit of overloading in the following example:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C07:UnionClass.cpp</font>
<font color=#009900>// Unions with constructors and member functions</font>
#include&lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>union</font> U {
<font color=#0000ff>private</font>: <font color=#009900>// Access control too!</font>
  <font color=#0000ff>int</font> i;
  <font color=#0000ff>float</font> f;
<font color=#0000ff>public</font>:  
  U(<font color=#0000ff>int</font> a);
  U(<font color=#0000ff>float</font> b);
  ~U();
  <font color=#0000ff>int</font> read_int();
  <font color=#0000ff>float</font> read_float();
};

U::U(<font color=#0000ff>int</font> a) { i = a; }

U::U(<font color=#0000ff>float</font> b) { f = b;}

U::~U() { cout &lt;&lt; <font color=#004488>"U::~U()\n"</font>; }

<font color=#0000ff>int</font> U::read_int() { <font color=#0000ff>return</font> i; }

<font color=#0000ff>float</font> U::read_float() { <font color=#0000ff>return</font> f; }

<font color=#0000ff>int</font> main() {
  U X(12), Y(1.9F);
  cout &lt;&lt; X.read_int() &lt;&lt; endl;
  cout &lt;&lt; Y.read_float() &lt;&lt; endl;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You might think from the code above that
the only <A NAME="Index1408"></A><A NAME="Index1409"></A>difference between a
<B>union</B> and a <B>class</B> is the way the data is stored (that is, the
<B>int</B> and <B>float</B> are overlaid on the same piece of storage). However,
a <B>union</B> cannot be used as a base class during inheritance, which is quite
limiting from an object-oriented design standpoint (you&#8217;ll learn about
inheritance in Chapter 14).</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Although the member functions civilize
access to the <B>union</B> somewhat, there is still no way to prevent the client
programmer from selecting the wrong element type once the <B>union</B> is
initialized. In the example above, you could say <B>X.read_float(&#160;)</B>
even though it is inappropriate. However, a
<A NAME="Index1410"></A><A NAME="Index1411"></A>&#8220;safe&#8221; <B>union</B>
can be encapsulated in a class. In the following example, notice how the
<B>enum</B> clarifies the code, and how overloading comes in handy with the
<A NAME="Index1412"></A><A NAME="Index1413"></A>constructors:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C07:SuperVar.cpp</font>
<font color=#009900>// A super-variable</font>
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>class</font> SuperVar {
  <font color=#0000ff>enum</font> {
    character,
    integer,
    floating_point
  } vartype;  <font color=#009900>// Define one</font>
  <font color=#0000ff>union</font> {  <font color=#009900>// Anonymous union</font>
    <font color=#0000ff>char</font> c;
    <font color=#0000ff>int</font> i;
    <font color=#0000ff>float</font> f;
  };
<font color=#0000ff>public</font>:
  SuperVar(<font color=#0000ff>char</font> ch);
  SuperVar(<font color=#0000ff>int</font> ii);
  SuperVar(<font color=#0000ff>float</font> ff);
  <font color=#0000ff>void</font> print();
};

SuperVar::SuperVar(<font color=#0000ff>char</font> ch) {
  vartype = character;
  c = ch;
}

SuperVar::SuperVar(<font color=#0000ff>int</font> ii) {
  vartype = integer;
  i = ii;
}

SuperVar::SuperVar(<font color=#0000ff>float</font> ff) {
  vartype = floating_point;
  f = ff;
}

⌨️ 快捷键说明

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