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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 4 页
字号:
   }
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.3 The ADAPTER Pattern</font></h2>
<font size="+1">

<ul>
	<li>When you want to use an existing class, but its i/f doesn't match the
		one you need</li>
	<li>Consider converting a string containing numerics (<tt>"235"</tt>) to
		an integer:
		<ul>
			<li><tt>string</tt> can't</li>
			<li>If digits were stored in a stream, great</li>
			<li>Hence, the <tt>istringstream</tt> class (chptr 12):
				<blockquote><tt>
					string s = "235";<br>
					istringstream istr(s);<br>
					int n;<br>
					s &gt;&gt; n;
						<font color="#0000cc">// Now n is the integer 235</font>
				</tt></blockquote>
			</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.3 The ADAPTER Pattern (cont.)</font></h2>
<font size="+1">

<ul>
	<li>The <tt>&gt;&gt;</tt> operator repeatedly calls <tt>get()</tt>, then
		assembles the integer</li>
	<li><tt>istringstream</tt> defines a <tt>get</tt> function to obtain the
		characters from a string, using <tt>string::operator[]</tt>
	<li>Example of the ADAPTER pattern</li>
</ul>

</font>

<hr><h2><font color="#009999">Pattern ADAPTER</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Context</font></h3>

<ol>
	<li>You want to use an existing class (<i>adaptee</i>) w/out modifying it</li>
	<li>The context requires conformance to a <i>target</i> i/f, different from
		the adaptee's</li>
	<li>Target i/f and adaptee i/f are conceptually related</li>
</ol>

</font>

<hr><h2><font color="#009999">Pattern ADAPTER (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Solution</font></h3>

<ol>
	<li>Define an <i>adapter</i> class that implements the target i/f</li>
	<li>Adapter class translates target functions to adaptee functions</li>
	<li>The client wraps the adaptee into an adapter class object</li>
</ol>

</font>

<hr><h2><font color="#009999">Pattern ADAPTER (cont.)</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Solution</font></h3>

<script><!--
	image( "un04.png" )
//--></script>

</font>

<hr><h2><font color="#009999">26.3 The ADAPTER Pattern (cont.)</font></h2>
<font size="+1">

<ul>
	<table border='1' cellpadding='4'>
		<tr bgcolor="#00ffff">
			<th width='50%'>Name in Design Pattern</th>
			<th width='50%'>Actual Name (String Streams)</th>
		</tr>
		<tr>
			<td align='center'><tt>Adaptee</tt></td>
			<td align='center'><tt>string</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Target</tt></td>
			<td align='center'><tt>istream</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Adapter</tt></td>
			<td align='center'><tt>istringstream</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Client</tt></td>
			<td align='center'>Code that wants to use <tt>operator&gt;&gt;</tt> to
				read string</td>
		</tr>
		<tr>
			<td align='center'><tt>target_function()</tt></td>
			<td align='center'><tt>get()</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>adaptee_function</tt></td>
			<td align='center'><tt>operator[]</tt></td>
		</tr>
	</table>
</ul>

</font>

<hr><h2><font color="#009999">26.3 The ADAPTER Pattern (cont.)</font></h2>
<font size="+1">

<h3>Other ADAPTERS:</h3>

<ul>
	<li><tt>ostream_iterator</tt> wraps a stream with an iterator i/f:
		<blockquote><tt>
			copy( source.begin(), source.end(),
				<nobr>ostream_iterator&lt;string&gt;</nobr>( cout, "\n" ));
		</tt></blockquote>
		<ul>
			<li>Overload the <tt>*</tt> and <tt>=</tt> operators</li>
			<li><tt>operator++</tt> overloaded to do nothing</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.3 The ADAPTER Pattern (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Can be used to read from a stream:
		<blockquote><tt>
			copy( <nobr>istream_iterator&lt;string&gt;(cin),</nobr>
			<nobr>istream_iterator&lt;string&gt;(),<nobr> target.begin() );
		</tt></blockquote>
		<ul>
			<li>Default c'tor, <tt>istream_iterator&lt;string&gt;()</tt>, creates
				end-of-stream sentinel</li>
			<li>Overload the <tt>*</tt> and <tt>!=</tt> operators</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.3 The ADAPTER Pattern (cont.)</font></h2>
<font size="+1">

<ul>
	<table border='1' cellpadding='4'>
		<tr bgcolor="#00ffff">
			<th width='50%'>Name in Design Pattern</th>
			<th width='50%'>Actual Name (String Streams)</th>
		</tr>
		<tr>
			<td align='center'><tt>Adaptee</tt></td>
			<td align='center'><tt>istream, ostream</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Target</tt></td>
			<td align='center'><tt>iterator</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Adapter</tt></td>
			<td align='center'><tt>istream_iterator, ostream_iterator</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>Client</tt></td>
			<td align='center'>Code that wants to use a stream</td>
		</tr>
		<tr>
			<td align='center'><tt>target_function()</tt></td>
			<td align='center'><tt>&lt;&lt;, &gt;&gt;, fail()</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>adaptee_function</tt></td>
			<td align='center'>The <tt>*, =, +, !=</tt> operators</td>
		</tr>
	</table>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern</font></h2>
<font size="+1">

<ul>
	<li>Pattern where an algorithm is mostly implemented in a base class, even
		when some details are unknown</li>
	<li>Details supplied in virtual methods in derived classes</li>
	<li>The base class template method tells how to fit in the details</li>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<p>Example - stream buffers</p>

<ul>
	<li>Each (buffered) stream has an associated stream</li>
	<li>Characters sent to buffer</li>
	<li>When buffer is full, contents are written to its target (file, screen,
		etc.)</li>
	<li>More efficient</li>
	<li><tt>ofstream</tt> and <tt>ostringstream</tt> differ only by the
		attached buffers:
		<ul>
			<li><tt>ofstream</tt> has a <tt>filebuf</tt> object</li>
			<li><tt>ostringstream</tt> has a <tt>stringbuf</tt> object</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<p>Example - stream buffers (cont.)</p>

<ul>
	<li>Consider an output operation:
		<blockquote><tt>
			cout &lt;&lt; "Hello, World!\n";
		</tt></blockquote>
	</li>
	<li>The appropriate <tt>operator&lt;&lt;</tt> is invoked:</li>
		<ul>
			<li>Converts each value into a sequence of characters</li>
			<li>Inserts each character into a stream buffer</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<p>Example - stream buffers (cont.)</p>

<ul>
	<li>One possible implementation:
		<blockquote>
<pre>ostream&amp; ostream::operator&lt;&lt;(const char s[])
{
   int i = 0;
   while (s[i] != '\0')
   {
      rdbuf()-&gt;sputc(s[i]); <font color="#0000cc">// returns a ptr to the buffer</font>
      i++;
   }
   return *this;
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<p>Example - stream buffers (cont.)</p>

<ul>
	<li>Insert a character into the buffer:
		<blockquote>
<pre>int streambuf::sputc(char c)
{
   if (buffer full )
      return overflow(c);
   else
   {
      add c to the buffer
      return c;
   }
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<p>Example - stream buffers (cont.)</p>

<ul>
	<li><tt>overflow</tt> writes the buffer content (and <tt>c</tt>) to its
		destination</li>
	<li><tt>overflow</tt> is a virtual method</li>
	<li>Has a dummy implementation in <tt>streambuf</tt>, returns <tt>EOF</tt>
		</li>
	<li>Derived classes redefine <tt>overflow</tt></li>
	<li><tt>streambuf::sputc</tt> is <b>not</b> redefined</li>
</ul>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li><tt>sputc</tt> is an example of the TEMPLATE METHOD Pattern</li>
		<ul>
			<li>(Nothing to do w/C++ templates)</li>
		</ul>
	<li>Base class defines an algorithm that calls
		<i>primitive operations</i></li>
	<li>Algorithm depends on derived class defining an appropriate operation</li>
	<li>The template method combines primitive operations into a larger
		algorithm</li>
</ul>

</font>

<hr><h2><font color="#009999">Pattern TEMPLATE METHOD</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Context</font></h3>

<ol>
	<li>An algorithm is applicable for multiple types</li>
	<li>Algorithm can be broken into <i>primitive operations</i></li>
	<li>The order of execution of the primitives doesn't depend on the type</li>
</ol>

</font>

<hr><h2><font color="#009999">Pattern TEMPLATE METHOD</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<h3><font color="#009999">Solution</font></h3>

<table cellpadding='5'>
	<tr>
		<td valign='top'><font size='+1'>
			<ol>
				<li>Define the algorithm in the base class</li>
				<li>The algorithm calls the primitive operations in order</li>
				<li>Define the primitive operations as virtual functions in base class,
			 		with appropriate default behavior, or leave undefined</li>
				<li>Each derived class defines the primitives, but not the algorithm
					</li>
			</ol>
		</font>
		</td>
		<td>
			<script><!--
				image( "un05.png" )
			//--></script>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">26.4 The TEMPLATE METHOD Pattern (cont.)
	</font></h2>
<font size="+1">

<ul>
	<table border='1' cellpadding='4'>
		<tr bgcolor="#00ffff">
			<th width='50%'>Name in Design Pattern</th>
			<th width='50%'>Actual Name (Stream Buffers)</th>
		</tr>
		<tr>
			<td align='center'><tt>AbstractClass</tt></td>
			<td align='center'><tt>streambuf</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>ConcreteClass</tt></td>
			<td align='center'><tt>filebuf, stringbuf</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>template_method()</tt></td>
			<td align='center'><tt>sputc</tt></td>
		</tr>
		<tr>
			<td align='center'><tt>primitive_op1</tt></td>
			<td align='center'><tt>overflow</tt></td>
		</tr>
	</table>
</ul>

</font>

<hr><h2><font color="#009999">26.5 Function Objects and the STRATEGY Pattern
	</font></h2>
<h2><font color="#009999">26.5.1 Function Objects</font></h2>
<font size="+1">

<ul>
	<li>STRATEGY pattern shows how to supply a variety of algorithms to a
		computation</li>
	<li>Motivation: the STL <tt>sort</tt></li>
	<li>E.g., sorting a vector of strings:
		<blockquote><tt>
			<nobr>vector&lt;string&gt;</nobr> names;<br>
			. . .<br>
			sort(<nobr>names.begin(),</nobr> <nobr>names.end()</nobr>);
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.5.1 Function Objects (cont.)</font></h2>
<font size="+1">

<ul>
	<li><tt>sort</tt> works on any type that has <tt>operator&lt;</tt></li>
	<li>Defined on strings, uses dictionary order</li>
	<li>Consider sorting Employees:
		<blockquote><tt>
			<nobr>vector&lt;Employee&gt;</nobr> staff;<br>
			sort(<nobr>staff.begin(),</nobr> <nobr>staff.end()</nobr>);
		</tt></blockquote>
	</li>
	<li>To sort by name, supply:
		<blockquote>
<pre>bool operator&lt;(const Employee&amp; a, const Employee&amp; b)
{
   return a.get_name() &lt; b.get_name();
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">26.5.1 Function Objects (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Sort by salary?</li>
	<li>Redefine <tt>operator&lt;</tt> for each sort order?</li>
	<li>Sol'n:  don't use the default <tt>operator&lt;</tt> 
		<blockquote><tt>
			SalaryComparator comp;<br>
			sort(<nobr>staff.begin(),</nobr> <nobr>staff.end(),</nobr> comp);
		</tt></blockquote>
	</li>
	<li>(more concisely):
		<blockquote><tt>
			sort(<nobr>staff.begin(),</nobr> <nobr>staff.end(),</nobr>
				<nobr>SalaryComparator()</nobr>);
		</tt></blockquote>
	</li>
	<li>Template function ptrs are messy, so we use a function object</li>
</ul>

</font>

<hr><h2><font color="#009999">26.5.1 Function Objects (cont.)</font></h2>
<font size="+1">

⌨️ 快捷键说明

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