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

📄 chap02.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 页 / 共 4 页
字号:
<font color=#0000ff>public</font>:
  StackError(<font color=#0000ff>const</font> string&amp; s) : logic_error(s) {}
};

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
<font color=#0000ff>class</font> Stack {
<font color=#0000ff>public</font>:
  Stack(size_t) <font color=#0000ff>throw</font>(StackError, bad_alloc);
  ~Stack();
  <font color=#0000ff>void</font> push(<font color=#0000ff>const</font> T&amp;) <font color=#0000ff>throw</font>(StackError);
  T pop() <font color=#0000ff>throw</font>(StackError);
  T top() <font color=#0000ff>const</font> <font color=#0000ff>throw</font>(StackError);
  size_t size() <font color=#0000ff>const</font>;
<font color=#0000ff>private</font>:
  T* data;
  size_t max;
  size_t ptr;
};

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
<font color=#0000ff>inline</font> Stack&lt;T&gt;::~Stack() {
  <font color=#0000ff>delete</font> [] data;
  max = ptr = 0;
}

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
<font color=#0000ff>inline</font> size_t Stack&lt;T&gt;::size() <font color=#0000ff>const</font> {
  <font color=#0000ff>return</font> ptr;
}

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
Stack&lt;T&gt;::Stack(size_t siz) 
  <font color=#0000ff>throw</font>(StackError, bad_alloc) {
  <font color=#0000ff>if</font> (siz == 0)
    <font color=#0000ff>throw</font> StackError(<font color=#004488>"bad size in Stack(size_t)"</font>);
  data = <font color=#0000ff>new</font> T[siz];
  max = siz;
  ptr = 0;
}

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
<font color=#0000ff>void</font> Stack&lt;T&gt;::push(<font color=#0000ff>const</font> T&amp; x) 
  <font color=#0000ff>throw</font>(StackError) {
  <font color=#0000ff>if</font> (ptr == max)
    <font color=#0000ff>throw</font> StackError(<font color=#004488>"stack overflow"</font>);

  assert(ptr &lt; max);
  data[ptr++] = x;
}

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
T Stack&lt;T&gt;::pop() <font color=#0000ff>throw</font>(StackError) {
  <font color=#0000ff>if</font> (ptr == 0)
    <font color=#0000ff>throw</font> StackError(<font color=#004488>"stack underflow"</font>);
  <font color=#0000ff>return</font> data[--ptr];
}

<font color=#0000ff>template</font>&lt;<font color=#0000ff>typename</font> T&gt;
T Stack&lt;T&gt;::top() <font color=#0000ff>const</font> <font color=#0000ff>throw</font>(StackError) {
  <font color=#0000ff>if</font> (ptr == 0)
    <font color=#0000ff>throw</font> StackError(<font color=#004488>"stack underflow"</font>);
  <font color=#0000ff>return</font> data[ptr - 1];
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It's easy to come up with general
categories of tests for this class. Here&#8217;s the class that defines the
tests:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C02:StackTest.h</font>
#ifndef STACKTEST_H
#define STACKTEST_H
#include <font color=#004488>"Stack.h"</font>
#include <font color=#004488>"..</font><font color=#004488>/TestSuite</font><font color=#004488>/Test.h"</font>
#include &lt;iostream&gt;
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>class</font> StackTest : <font color=#0000ff>public</font> Test {
  <font color=#0000ff>enum</font> {SIZE = 5};
  Stack&lt;<font color=#0000ff>int</font>&gt; stk;
<font color=#0000ff>public</font>:
  StackTest() : stk(SIZE){}
  <font color=#0000ff>void</font> run(){
    testUnderflow();
    testPopulate();
    testOverflow();
    testPop();
    testBadSize();
  }
  <font color=#0000ff>void</font> testBadSize(){
    <font color=#0000ff>try</font> {
      Stack&lt;<font color=#0000ff>int</font>&gt; s(0);
      fail_(<font color=#004488>"Bad Size"</font>);
    }
    <font color=#0000ff>catch</font> (StackError&amp;) {
      succeed_();
    }
  }
  <font color=#0000ff>void</font> testUnderflow(){
    test_(stk.size() == 0);
    <font color=#0000ff>try</font> {
      stk.top();
      fail_(<font color=#004488>"Underflow"</font>);
    }
    <font color=#0000ff>catch</font> (StackError&amp;) {
      succeed_();
    }
    <font color=#0000ff>try</font> {
      stk.pop();
      fail_(<font color=#004488>"Underflow"</font>);
    }
    <font color=#0000ff>catch</font> (StackError&amp;) {
      succeed_();
    }
  }
  <font color=#0000ff>void</font> testPopulate(){
    <font color=#0000ff>try</font> {
      <font color=#0000ff>for</font> (<font color=#0000ff>int</font> i = 0; i &lt; SIZE; ++i)
        stk.push(i);
      succeed_();
    }
    <font color=#0000ff>catch</font> (StackError&amp;) {
      fail_(<font color=#004488>"Populate"</font>);
    }
    test_(stk.size() == SIZE);
    test_(stk.top() == SIZE-1);
  }
  <font color=#0000ff>void</font> testOverflow(){
    <font color=#0000ff>try</font> {
      stk.push(SIZE);
      fail_(<font color=#004488>"Overflow"</font>);
    }
    <font color=#0000ff>catch</font> (StackError&amp;) {
      succeed_();
    }
  }
  <font color=#0000ff>void</font> testPop(){
    <font color=#0000ff>for</font> (<font color=#0000ff>int</font> i = 0; i &lt; SIZE; ++i)
      test_(stk.pop() == SIZE-i-1);
    test_(stk.size() == 0);
  }
}; 
#endif <font color=#009900>// STACKTEST_H ///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s a <B>main(&#160;)</B> that
exercises the tests:</FONT><BR></P></DIV>

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

<font color=#0000ff>int</font> main() {
  StackTest t;
  t.run();
  t.report();
  <font color=#0000ff>return</font> t.getNumFailed();
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To test whether exceptions are working
correctly, you have to generate an exception and call <B>succeed_</B> or
<B>fail_</B> explicitly, as <B>StackTest::testBadSize(&#160;)</B> class
illustrates, above. Since a stack of size zero is prohibited, "success" in this
case means that a <B>StackError</B> exception was caught, so I have to call
<B>succeed_</B> explicitly.</FONT><A NAME="_Toc519041908"></A><BR></P></DIV>
<A NAME="Heading66"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
Test Suites</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Real projects usually contain many
classes, so there needs to be a way to group tests together so you can just push
a single button to test the entire project. The <B>Suite</B> class allows you to
collect tests into a functional unit. You add a derived <B>Test</B> object to a
<B>Suite</B> with the <B>addTest(&#160;)</B> method, or you can swallow an
entire existing Suite with <B>addSuite(&#160;)</B>. To illustrate, the following
example combines the foregoing <B>DateTest</B> and <B>StackTest</B> into a
suite. Here's an actual test run:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C02:SuiteExample.cpp</font>
<font color=#009900>//{L} ../TestSuite/Test ../TestSuite/Suite Date</font>
#include &lt;iostream&gt;
#include <font color=#004488>"..</font><font color=#004488>/TestSuite</font><font color=#004488>/Suite.h"</font>
#include <font color=#004488>"DateTest.h"</font>
#include <font color=#004488>"StackTest.h"</font>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>int</font> main() {
  Suite s(<font color=#004488>"Date and Stack Tests"</font>);
  s.addTest(<font color=#0000ff>new</font> DateTest);
  s.addTest(<font color=#0000ff>new</font> StackTest);
  s.run();
  <font color=#0000ff>long</font> nFail = s.report();
  s.free();
  cout &lt;&lt; <font color=#004488>"\nTotal failures: "</font> &lt;&lt; nFail &lt;&lt; endl;
  <font color=#0000ff>return</font> nFail;
}

<font color=#009900>/* Output:
Suite "Date and Stack Tests"
============================
Test "DateTest":
	Passed: 7	Failed: 0
Test "StackTest":
	Passed: 14	Failed: 0
============================

Total failures: 0
*/</font> <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Suite::run calls Test::run for each of
its contained tests. Much the same thing happens for Suite::report. Individual
test results can be written to separate streams, if desired. If the test passed
to addSuite has a stream pointer assigned already, it keeps it. Otherwise it
gets its stream from the Suite object. The code for Suite is in listing 5 and 6.
As you can see, Suite just holds a vector of pointers to Test. When it's time to
run each test, it just loops through the tests in the vector calling their run
method.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It takes some discipline to write unit
tests before you code, but if you have an automated tool, it makes it a lot
easier. I just add a project in my IDE for a test suite for each project, and
switch back and forth between the test and the real code as needed. There's no
conceptual baggage, no extra test scripting language to learn, no worries
&#8212; just point, click, and
test!</FONT><A NAME="_Toc519041909"></A><BR></P></DIV>
<A NAME="Heading67"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
The Test Framework Code</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The test framework code library will be
placed in a subdirectory called <B>TestSuite</B>. To use it, therefore, you must
have the <B>TestSuite</B> subdirectory in your header include search path, and
you must link the object files, and thus it must also be included in the library
search path (?? or compiled into a library ??).</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is the header for
Test.h:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: TestSuite:Test.h</font>
#ifndef TEST_H
#define TEST_H
#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;cassert&gt;
<font color=#0000ff>using</font> std::string;
<font color=#0000ff>using</font> std::ostream;
<font color=#0000ff>using</font> std::cout;

<font color=#009900>// The following have underscores because they </font>
<font color=#009900>// are macros (and it's impolite to usurp other </font>
<font color=#009900>// users' functions!). For consistency, </font>
<font color=#009900>// succeed_() also has an underscore.</font>

#define test_(cond) \
  do_test(cond, #cond, __FILE__, __LINE__)
#define fail_(str) \
  do_fail(str, __FILE__, __LINE__)

<font color=#0000ff>class</font> Test {
<font color=#0000ff>public</font>:
  Test(ostream* osptr = &amp;cout);
  <font color=#0000ff>virtual</font> ~Test(){}
  <font color=#0000ff>virtual</font> <font color=#0000ff>void</font> run() = 0;
  <font color=#0000ff>long</font> getNumPassed() <font color=#0000ff>const</font>;
  <font color=#0000ff>long</font> getNumFailed() <font color=#0000ff>const</font>;
  <font color=#0000ff>const</font> ostream* getStream() <font color=#0000ff>const</font>;
  <font color=#0000ff>void</font> setStream(ostream* osptr);
  <font color=#0000ff>void</font> succeed_();
  <font color=#0000ff>long</font> report() <font color=#0000ff>const</font>;
  <font color=#0000ff>virtual</font> <font color=#0000ff>void</font> reset();
<font color=#0000ff>protected</font>:
  <font color=#0000ff>void</font> do_test(<font color=#0000ff>bool</font> cond, <font color=#0000ff>const</font> string&amp; lbl,
               <font color=#0000ff>const</font> <font color=#0000ff>char</font>* fname, <font color=#0000ff>long</font> lineno);
  <font color=#0000ff>void</font> do_fail(<font color=#0000ff>const</font> string&amp; lbl,
               <font color=#0000ff>const</font> <font color=#0000ff>char</font>* fname, <font color=#0000ff>long</font> lineno);
<font color=#0000ff>private</font>:
  ostream* osptr;
  <font color=#0000ff>long</font> nPass;
  <font color=#0000ff>long</font> nFail;
  <font color=#009900>// Disallowed:</font>
  Test(<font color=#0000ff>const</font> Test&amp;);
  Test&amp; <font color=#0000ff>operator</font>=(<font color=#0000ff>const</font> Test&amp;);

⌨️ 快捷键说明

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