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

📄 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>const</font> <font color=#0000ff>int</font> daysInMonth[][13] = {
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}};
  <font color=#0000ff>inline</font> <font color=#0000ff>bool</font> isleap(<font color=#0000ff>int</font> y) {
    <font color=#0000ff>return</font> y%4 == 0 &amp;&amp; y%100 != 0 || y%400 == 0;
  }
}

Date::Date() {
  <font color=#009900>// Get current date</font>
  time_t tval = time(0);
  <font color=#0000ff>struct</font> tm *now = localtime(&amp;tval);
  year = now-&gt;tm_year + 1900;
  month = now-&gt;tm_mon + 1;
  day = now-&gt;tm_mday;
}

Date::Date(<font color=#0000ff>int</font> yr, <font color=#0000ff>int</font> mon, <font color=#0000ff>int</font> dy) {
  assert(1 &lt;= mon &amp;&amp; mon &lt;= 12);
  assert(1 &lt;= dy &amp;&amp; 
    dy &lt;= daysInMonth[isleap(year)][mon]);
  year = yr;
  month = mon;
  day = dy;
}

Date::Date(<font color=#0000ff>const</font> std::string&amp; s) {
  <font color=#009900>// Assume YYYYMMDD format</font>
  istringstream is(s);
  is &gt;&gt; setw(4) &gt;&gt; year;
  is &gt;&gt; setw(2) &gt;&gt; month;
  is &gt;&gt; setw(2) &gt;&gt; day;
}

<font color=#0000ff>int</font> Date::getYear() <font color=#0000ff>const</font> {
  <font color=#0000ff>return</font> year;
}

<font color=#0000ff>int</font> Date::getMonth() <font color=#0000ff>const</font> {
  <font color=#0000ff>return</font> month;
}

<font color=#0000ff>int</font> Date::getDay() <font color=#0000ff>const</font> {
  <font color=#0000ff>return</font> day;
}

string Date::toString() <font color=#0000ff>const</font> {
  ostringstream os;
  os &lt;&lt; setw(4) &lt;&lt; year
   &lt;&lt; setw(2) &lt;&lt; month
   &lt;&lt; setw(2) &lt;&lt; day;
  <font color=#0000ff>return</font> os.str();
}

<font color=#0000ff>int</font> Date::compare(<font color=#0000ff>const</font> Date&amp; d2) <font color=#0000ff>const</font> {
  <font color=#0000ff>int</font> result = year - d2.year;
  <font color=#0000ff>if</font> (result == 0) {
    result = month - d2.month;
    <font color=#0000ff>if</font> (result == 0)
      result = day - d2.day;
  }
  <font color=#0000ff>return</font> result;   
}

<font color=#0000ff>int</font> Date::daysInPrevMonth(<font color=#0000ff>int</font> year, <font color=#0000ff>int</font> month) {
  <font color=#0000ff>if</font> (month == 1) {
    --year;
    month = 12;
  }
  <font color=#0000ff>else</font>
    --month;
  <font color=#0000ff>return</font> daysInMonth[isleap(year)][month];
}

<font color=#0000ff>bool</font> <font color=#0000ff>operator</font>&lt;(<font color=#0000ff>const</font> Date&amp; d1, <font color=#0000ff>const</font> Date&amp; d2) {
  <font color=#0000ff>return</font> d1.compare(d2) &lt; 0;
}
<font color=#0000ff>bool</font> <font color=#0000ff>operator</font>&lt;=(<font color=#0000ff>const</font> Date&amp; d1, <font color=#0000ff>const</font> Date&amp; d2) {
  <font color=#0000ff>return</font> d1.compare(d2) &lt;= 0;
}
<font color=#0000ff>bool</font> <font color=#0000ff>operator</font>&gt;(<font color=#0000ff>const</font> Date&amp; d1, <font color=#0000ff>const</font> Date&amp; d2) {
  <font color=#0000ff>return</font> d1.compare(d2) &gt;= 0;
}
<font color=#0000ff>bool</font> <font color=#0000ff>operator</font>&gt;=(<font color=#0000ff>const</font> Date&amp; d1, <font color=#0000ff>const</font> Date&amp; d2) {
  <font color=#0000ff>return</font> d1.compare(d2) &gt;= 0;
}
<font color=#0000ff>bool</font> <font color=#0000ff>operator</font>==(<font color=#0000ff>const</font> Date&amp; d1, <font color=#0000ff>const</font> Date&amp; d2) {
  <font color=#0000ff>return</font> d1.compare(d2) == 0;
}
<font color=#0000ff>bool</font> <font color=#0000ff>operator</font>!=(<font color=#0000ff>const</font> Date&amp; d1, <font color=#0000ff>const</font> Date&amp; d2) {
  <font color=#0000ff>return</font> d1.compare(d2) != 0;
}

Duration 
duration(<font color=#0000ff>const</font> Date&amp; date1, <font color=#0000ff>const</font> Date&amp; date2) {
  <font color=#0000ff>int</font> y1 = date1.year;
  <font color=#0000ff>int</font> y2 = date2.year;
  <font color=#0000ff>int</font> m1 = date1.month;
  <font color=#0000ff>int</font> m2 = date2.month;
  <font color=#0000ff>int</font> d1 = date1.day;
  <font color=#0000ff>int</font> d2 = date2.day;

  <font color=#009900>// Compute the compare</font>
  <font color=#0000ff>int</font> order = date1.compare(date2);
  <font color=#0000ff>if</font> (order == 0)
    <font color=#0000ff>return</font> Duration(0,0,0);
  <font color=#0000ff>else</font> <font color=#0000ff>if</font> (order &gt; 0) {
    <font color=#009900>// Make date1 precede date2 locally</font>
    <font color=#0000ff>using</font> std::swap;
    swap(y1, y2);
    swap(m1, m2);
    swap(d1, d2);
  }

  <font color=#0000ff>int</font> years = y2 - y1;
  <font color=#0000ff>int</font> months = m2 - m1;
  <font color=#0000ff>int</font> days = d2 - d1;
  assert(years &gt; 0 ||
     years == 0 &amp;&amp; months &gt; 0 ||
     years == 0 &amp;&amp; months == 0 &amp;&amp; days &gt; 0);

  <font color=#009900>// Do the obvious corrections (must adjust days</font>
  <font color=#009900>// before months!) - This is a loop in case the</font>
  <font color=#009900>// previous month is February, and days &lt; -28.</font>
  <font color=#0000ff>int</font> lastMonth = m2;
  <font color=#0000ff>int</font> lastYear = y2;
  <font color=#0000ff>while</font> (days &lt; 0) {
    <font color=#009900>// Borrow from month</font>
    assert(months &gt; 0);
    days += Date::daysInPrevMonth(
      lastYear, lastMonth--);
    --months;
  }

  <font color=#0000ff>if</font> (months &lt; 0) {
    <font color=#009900>// Borrow from year</font>
    assert(years &gt; 0);
    months += 12;
    --years;
  }
  <font color=#0000ff>return</font> Duration(years, months, days);
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can now write tests for the functions
you want to implement first, something like the following:</FONT><BR></P></DIV>

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

<font color=#0000ff>int</font> nPass = 0, nFail = 0;
<font color=#0000ff>void</font> test(<font color=#0000ff>bool</font> t) {
  <font color=#0000ff>if</font>(t) nPass++; <font color=#0000ff>else</font> nFail++;
}

<font color=#0000ff>int</font> main() {
  Date mybday(1951, 10, 1);
  test(mybday.getYear() == 1951);
  test(mybday.getMonth() == 10);
  test(mybday.getDay() == 1);
  cout &lt;&lt; <font color=#004488>"Passed: "</font> &lt;&lt; nPass &lt;&lt; <font color=#004488>", Failed: "</font>
       &lt;&lt; nFail &lt;&lt; endl;
}
<font color=#009900>/* Output:
Passed: 3, Failed: 0
*/</font> <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In this trivial case, the function
<B>test(&#160;)</B> maintains the global variables <B>nPass</B> and
<B>nFail</B>. The only visual inspection you do is to read the final score. If a
test failed, then a more sophisticated <B>test(&#160;)</B> would print out an
appropriate message. The framework described below has such a
<B>test(&#160;)</B> function, among other things.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As you continue in the test-and-code
cycle you'll want to build a suite of tests that are always available to keep
all your related classes in good shape through any future maintenance. As
requirements change, you add or modify tests
accordingly.</FONT><A NAME="_Toc519041907"></A><BR></P></DIV>
<A NAME="Heading65"></A><FONT FACE = "Verdana, Tahoma, Arial, Helvetica, Sans"><H3 ALIGN="LEFT">
The TestSuite Framework</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As you learn more about XP you'll
discover that there are some automated unit test tools available for download,
such as JUnit for Java and CppUnit for C++. These are brilliantly designed and
implemented, but I want something even simpler. I want something that I can not
only easily use but also understand internally and even tweak if necessary. And
I can live without a GUI. So, in the spirit of
TheSimplestThingThatCouldPossiblyWork, I present the <I>TestSuite Framework</I>,
as I call it, which consists of two classes: <B>Test</B> and <B>Suite</B>. You
derive from <B>Test</B> (an abstract class) to override the <B>run(&#160;)</B>
method, which should in turn call <B>test_</B> for each Boolean test condition
you define. For the <B>Date</B> class above you could do something like the
following:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C02:DateTest.h</font>
#include <font color=#004488>"..</font><font color=#004488>/TestSuite</font><font color=#004488>/Test.h"</font>
#include <font color=#004488>"Date.h"</font>

<font color=#0000ff>class</font> DateTest : <font color=#0000ff>public</font> Test {
  Date mybday;
  Date today;
<font color=#0000ff>public</font>:
  DateTest()
    : mybday(1951, 10,1) {}
  <font color=#0000ff>void</font> run() {
    testOps();
    testDuration();
  }
  <font color=#0000ff>void</font> testOps() {
    test_(mybday &lt; today);
    test_(mybday &lt;= today);
    test_(mybday != today);
    test_(mybday == mybday);
  }
  <font color=#0000ff>void</font> testDuration() {
    Date d2(2001, 7, 4);
    Duration dur = duration(mybday, d2);
    test_(dur.years == 49);
    test_(dur.months == 9);
    test_(dur.days == 3);
  }
}; <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can now run the test very easily,
like this:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C02:DateTest.cpp</font>
<font color=#009900>// Automated Testing (with a Framework)</font>
<font color=#009900>//{L} Date ../TestSuite/Test</font>
#include &lt;iostream&gt;
#include <font color=#004488>"DateTest.h"</font>
<font color=#0000ff>using</font> <font color=#0000ff>namespace</font> std;

<font color=#0000ff>int</font> main() {
  DateTest test;
  test.run();
  test.report();
  <font color=#0000ff>return</font> test.getNumFailed();
}
<font color=#009900>/* Output:
Passed: 7, Failed: 0
*/</font> <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As development continues on the
<B>Date</B> class, you'll add other tests called from
<B>DateTest::run(&#160;)</B>, and then execute the main program to see if they
all pass.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>Test</B> class uses RTTI to get
the name of your class (e.g., <B>DateTest</B>) for the
report</FONT><A NAME="fnB7" HREF="#fn7">[7]</A><FONT FACE="Georgia">. The
<B>setStream(&#160;)</B> method lets you specify where the output will go, and
report sends output to that stream. <B>Test</B> is implemented later in this
section. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In addition to <B>test_</B>, the
framework includes the functions <B>succeed_</B> and <B>fail_</B>, for cases
where a Boolean test won't do. For example, a simple <B>Stack</B> class template
might look like this:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C02:Stack.h</font>
#include &lt;cassert&gt;
#include &lt;cstddef&gt;
#include &lt;stdexcept&gt;
#include &lt;string&gt;
#include &lt;<font color=#0000ff>new</font>&gt;

<font color=#0000ff>using</font> std::logic_error;
<font color=#0000ff>using</font> std::string;
<font color=#0000ff>using</font> std::bad_alloc;

<font color=#009900>// MS std namespace work-around</font>
#ifndef _MSC_VER
<font color=#0000ff>using</font> std::size_t;
#endif

<font color=#0000ff>class</font> StackError : <font color=#0000ff>public</font> logic_error {

⌨️ 快捷键说明

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