📄 index.html
字号:
<tr>
<td valign="top"><font size="+1" color="#009999">
Example:</font></td>
<td><font size="+1">
<pre>class List
{
. . .
class Iterator;
};</pre>
</font>
</td>
</tr>
<tr>
<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
<td><font size="+1">Declare a class whose scope is contained in the
scope of another class</font></td>
</tr>
</table>
</font>
</td>
</tr>
</table>
</font>
<hr><h2><font color="#009999">20.5 Nested Classes (cont.)</font></h2>
<font size="+1">
<p>To nest <tt>Iterator</tt> (chptr. 16) inside <tt>List</tt>:</p>
<ul>
<li>Will be used as:
<blockquote><tt>
List::Iterator pos = staff.begin();
</tt></blockquote>
</li>
<li>Declare the nested class w/a forward reference in outer class:
<blockquote>
<pre>class List
{
. . .
class Iterator; // Forward reference
. . .
};</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.5 Nested Classes (cont.)</font></h2>
<font size="+1">
<ul>
<li>Define class and its methods, always referring to its full name:
<blockquote>
<pre>class List::Iterator
{
public:
Iterator();
string get() const;
. . .
};
List::Iterator::Iterator()
{ . . . }
string List::Iterator::get() const
{ . . . }</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.5 Nested Classes (cont.)</font></h2>
<font size="+1">
<p>Or, include the <i>entire</i> definition inside the outer class:</p>
<blockquote>
<pre>class List
{
. . .
class Iterator
{
public:
Iterator();
string get() const;
. . .
};
. . .
};</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">20.5 Nested Classes (cont.)</font></h2>
<font size="+1">
<ul>
<li>Does <i>not</i> imply that a <tt>List</tt> object contains an
<tt>Iterator</tt> object</li>
<li>The name <tt>Iterator</tt> is in the scope of the <tt>List</tt>
class</li>
<li><tt>List</tt> member functions can refer to it simply as
<tt>Iterator</tt></li>
<li>All other functions refer to it as <tt>List::Iterator</tt></li>
<li>Nested classes need not be public</li>
<li>Declaring nested class as <tt>private</tt> encapsulates entire
definition
<ul>
<li>May only be created by members of outer class</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.5 <tt>private</tt> Nested Class -
Example</font></h2>
<font size="+1">
<p>From chptr. 18:</p>
<ul>
<li><tt>StringReference</tt> is private to <tt>SharedString</tt></li>
<li>Though all attributes are public, they are local to
<tt>SharedString</tt></li>
</ul>
</font>
<hr><h2><font color="#009999">20.5 <tt>private</tt> Nested Class -
Example (cont.)</font></h2>
<font size="+1">
<blockquote>
<pre>class SharedString
{
. . .
private:
<font color="#009999">class StringReference</font>;
. . .
};
class SharedString::StringReference
{
public:
int count;
char* buffer;
StringReference(const char* right);
~StringReference();
};</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">Quality Tip 20.4</font></h2>
<font size="+1">
<hr noshade size="6" color="#00ffff">
<font color="#009999" size="+2"><p>Manage Encapsulation</p></font>
<ul>
<li>Tools to manage encapsulation:</li>
<ul>
<li>class definitions</li>
<li>access modifiers</li>
<li>nested classes</li>
<li>namespaces</li>
</ul>
</li>
<li>There are often several ways to address a problem</li>
<li>Consider the results of the various methods</li>
<li>Plan carefully</li>
</ul>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance and
Names</font></h2>
<font size="+1">
<ul>
<li>Inheritance normally implies an "is-a" relationship
<ul>
<li><i>Substitution principle</i>: If <tt>B</tt> inherits from
<tt>A</tt>, then <tt>B</tt> can be used wherever <tt>A</tt> is
expected</li>
<li>Interface for the base class becomes a basis for the i/f for the
derived class</li>
</ul>
</li>
<li>We occasionally use inheritance even when the "is-a" relationship
doesn't hold (see example)
<ul>
<li>A solution is to declare that <tt>Set</tt> inherits privately from
<tt>List</tt></li>
<li>With <i>private inheritance</i> all inherited attributes become
private in the derived class</li>
<li>The base class' interface does not flow through to the derived
class</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance and Names -
syntax</font></h2>
<font size="+1">
<table border="1" cellpadding="4" bgcolor="#00cccc">
<tr>
<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.4:
Private Inheritance</font>
<pre>class <i>DerivedClassName</i> : private <i>BaseClassName</i>
{
<i>features</i>;
}</pre>
<table border="0" cellpadding="4">
<tr>
<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
<td><font size="+1">To allow the derived class access to the
functionality of the base class, without declaring the derived
class as a specialized form of the base class.</font></td>
</tr>
</table>
</td>
</tr>
</table>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance and Names -
syntax (cont.)</font></h2>
<font size="+1">
<table width='100%' border="1" cellpadding="4" bgcolor="#00cccc">
<tr>
<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.4:
Private Inheritance (cont.)</font>
<table border="0" cellpadding="4">
<tr>
<td valign="top"><font size="+1" color="#009999">
Example:</font></td>
<td><font size="+1">
<pre>class Set : private List
{
public:
void add(string s);
Iterator erase(Iterator pos);
Iterator begin();
Iterator end();
};</pre>
</font>
</td>
</tr>
</table>
</font>
</td>
</tr>
</table>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance - example</font></h2>
<font size="+1">
<ul>
<li>Inherit from <tt>List</tt> to implement <tt>Set</tt></li>
<li>But many of the <tt>List</tt> methods would be inappropriate for a
<tt>Set</tt></li>
</ul>
<blockquote>
<pre>class Set : private List
{
public:
void add(string s);
Iterator erase(Iterator pos);
Iterator begin();
Iterator end();
};</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance - example
(cont.)</font></h2>
<font size="+1">
<blockquote>
<pre>void Set::add(string s)
{
Iterator iter = begin();
Iterator stop = end();
while (iter != stop)
{
if (s.equals(iter.get()))
return; // Already in set, dont add
}
push_back(s); // Can use inherited push_back method
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance - example
(cont.)</font></h2>
<font size="+1">
<blockquote>
<pre>Iterator Set::erase(Iterator pos)
{
List::erase(pos);
}
Iterator Set::begin()
{
return List::begin();
}
Iterator Set::end()
{
return List::end();
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">20.6 Private Inheritance - example
(cont.)</font></h2>
<font size="+1">
<ul>
<li><tt>Set</tt> method may call <tt>push_back</tt></li>
<li><tt>push_back</tt> is <i>not</i> part of <tt>Set</tt>'s interface:
<blockquote><tt>
Set a_set;<br>
a_set.add("Sally"); <font color="#0000cc">// legal</font><br>
a_set.push_back("Fred"); <font color="#ff0000"><br>
// Error--push_back not part of interface for Set</font>
</tt></blockquote>
</li>
<li>Private inheritance is rarely used</li>
<li><tt>Set</tt> could've instead had a private <tt>List</tt>
attribute (<i>aggregation</i>)</li>
<li>Similarly, <i>protected inheritance</i> exists, but is used even
less often</li>
</ul>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces</font></h2>
<font size="+1">
<ul>
<li>Mechanism to avoid naming conflicts:
<ul>
<li>Consider a programmer who creates a <tt>map</tt> class, e.g., for
a computer game</li>
<li>There is already a <tt>map</tt> class in the STL</li>
<li>But, all the STL classes are in the <tt>std</tt> namespace</li>
<li>Can reference <tt>std::map</tt> explicitly</li>
<li>Could alternatively (or additionally) put the other <tt>map</tt>
class in another namespace</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces - syntax</font></h2>
<font size="+1">
<table width='90%' border="1" cellpadding="4" bgcolor="#00cccc">
<tr>
<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.5:
Name Space Definition</font>
<pre>namespace <i>name_space_name</i>
{
<i>feature</i><sub>1</sub>
<i>feature</i><sub>2</sub>
. . .
<i>feature<sub>n</sub></i>
}</pre>
</td>
</tr>
</table>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces - syntax (cont.)</font></h2>
<font size="+1">
<table width='90%' border="1" cellpadding="4" bgcolor="#00cccc">
<tr>
<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.5:
Name Space Definition (cont.)</font>
<table border="0" cellpadding="4">
<tr>
<td valign="top"><font size="+1" color="#009999">
Example:</font></td>
<td><font size="+1">
<pre>namespace ACME_Software_San_Jose_CA_US
{
class map
{
. . .
};
}</pre>
</font>
</td>
</tr>
<tr>
<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
<td><font size="+1">Include a class, function, or variable in a
name space.</font></td>
</tr>
</table>
</font>
</td>
</tr>
</table>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces (cont.)</font></h2>
<font size="+1">
<ul>
<li>Wrap declarations in a <tt>namespace</tt> block to add names to a
namespace:
<blockquote>
<pre>namespace acme
{
class map
{
. . .
};
void draw(map m);
}</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces (cont.)</font></h2>
<font size="+1">
<ul>
<li>Name spaces are <i>open</i>; add items by creating another block w/the
same name:
<blockquote>
<pre>namespace acme
{
class maze
{
. . .
};
}</pre>
</blockquote>
</li>
<li>Use unambiguous (long) names for namespaces</li>
</ul>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces - the <tt>using</tt>
directive</font></h2>
<font size="+1">
<ul>
<li>Dumps entire namespace (or selected names) into global namespace</li>
<li>Avoids using fully qualified names</li>
<li>Beware of conflicts</li>
<li>To add entire namespace:
<blockquote><tt>
using namespace std;
</tt></blockquote>
</li>
<li>To pick which names to add:
<blockquote><tt>
using std::cout; <font color="#0000cc">
// Include only cout from the std namespace</font>
</tt></blockquote>
</li>
<li>Do <i>not</i> put <tt>using</tt> statements in header (included)
files</li>
</ul>
</font>
<hr><h2><font color="#009999">20.7 Name Spaces Alias</font></h2>
<font size="+1">
<ul>
<li>Use a short alias for a long namespace name:</li>
</ul>
<table border="1" cellpadding="4" bgcolor="#00cccc">
<tr>
<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.6:
Name Space Alias</font>
<pre>namespace <i>alias_name</i> = <i>name_space_name</i>;</pre>
<table border="0" cellpadding="4">
<tr>
<td valign="top"><font size="+1" color="#009999">
Example:</font></td>
<td><font size="+1">
<pre>namespace acme = ACME_Software_San_Jose_CA_US;</pre>
</font>
</td>
</tr>
<tr>
<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
<td><font size="+1">Introduce a short alias for the long name of
a name space</font></td>
</tr>
</table>
</font>
</td>
</tr>
</table>
<ul>
<li>You can use different alias names for the same namespace in different
files</li>
</ul>
</font>
<hr><h2><font color="#009999">20.8 Case Study: Matrices,
Continued</font></h2>
<font size="+1">
<ul>
<li><tt>MatrixRow</tt> and <tt>ConstMatrixRow</tt> are nested in
<tt>Matrix</tt>
<ul>
<li>Renamed to <tt>Row</tt> and <tt>constRow</tt></li>
<li>Declared as <tt>private</tt>, since they won't be created outside
of <tt>Matrix</tt>
<li>Replaced references to </tt>MatrixRow</tt> with <tt>Matrix::Row</tt>
</li>
</ul>
</li>
<li>Nested <tt>MatrixIndexException</tt> and <tt>MatrixMismatchException</tt>
inside <tt>Matrix</tt></li>
<li>Wrapped all classes in the <tt>BigCPlusPlus_Matrix</tt> namespace
<ul>
<li>No <tt>using</tt> statements in header file</li>
<li>Test file aliases and imports all of <tt>BigCPlusPlus_Matrix</tt>,
and <tt>std::cout</tt></li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">20.8 Case Study: Matrices
(<tt>matrix4.h</tt>)</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "matrix4.h", "80%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">20.8 Case Study: Matrices
(<tt>matrix4.cpp</tt>)</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "matrix4.cpp", "80%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">20.8 Case Study: Matrices
(<tt>matrixtest4.cpp</tt>)</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "matrixtest4.cpp", "80%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">Chapter Summary</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">
<ol>
<li>Encapsulation helps reduce the number of visible names</li>
<li>Scope refers to the portions of a program where a name
is visible</li>
<li>A variable that hides another variable of the same name in a different
scope is said to shadow the hidden name</li>
<li><tt>protected</tt> members are accessible to derived classes</li>
<li>A friend is a function or another class that is granted access
to all features of a class</li>
<li>A nested class is defined inside another class to limit the nested
class' names to the outer class' scope</li>
</ul>
</font>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -