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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!-- -*-html-*-
	$Source: /usr/local/cvsroot/BigC++/20/index.html,v $
	$Revision: 1.4 $
	Big C++, chptr 20
	editor: cols=80, tabstop=2

	(c) 2005 John Wiley & Sons
	Kurt Schmidt, kschmidt@cs.drexel.edu

	NOTES
	- 3 spaces are used for each indent in examples

	REVISIONS:
		12/19/03 - creation
		1/10/04 - fixed spelling
		$Log: index.html,v $
		Revision 1.4  2004/03/29 05:49:16  kurt
		Pared language, fixed tabs (spaces), added copyright to comments
		
-->

<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
	<meta name="Copyright" content="2005 John Wiley & Sons">
	<meta name="Author" content="Kurt Schmidt">
	<script language="JavaScript" src="./config.js"></script>
	<script language="JavaScript" src="./pageFormat.js"></script>
	<script><!-- // Set title on page
		title()
	//--></script>
</head>

<body>

<h2><font color="#009999" size="+3">Chapter 20: Name Scope
		Management</font></h2>
<font size="+1">

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

</font>

<hr><h2><font color="#009999" size="+2">Chapter Goals</font></h2>
<hr noshade size="4" color="#009999">
<font size="+1">

<ul>
	<li>To understand how the management of names is tied to the management
		of values</li>
	<li>To understand the concepts of scope and visibility, and the various
		scopes found in C++ programs</li>
	<li>To learn how to use protected visibility to create an interface for
		derived classes that is different from the public interface</li>
	<li>To understand the use of alternative techniques for the management of
		names, such as friends, nested classes, and private inheritance</li>
	<li>To learn how to avoid ambiguity and duplicate names by using independent
		name spaces</li>
</ul>

</font>

<hr><h2><font color="#009999">20.1 Encapsulation</font></h2>
<font size="+1">

<ul>
	<li>Control complexity arising from name collisions</li>
	<li>Hide or restrict access to members (sect. 6.3):
		<blockquote>
<pre>class Product
{
public:
   Product();
   void read();
   bool is_better_than(Product b) const;
   void print() const;
<font color="#009999">private:
   string name;
   double price;
   int score;</font>
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">20.1 Encapsulation (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Encapsulation restricts access to <i>names</i></li>
	<li>Same as restricting access to values</li>
	<li>E.g., P1 creates a stack class that P2 will use (prev. chapter):
		<ul>
			<li>Encapsulation limits the information P2 must know</li>
			<li>Data fields are inaccessible to P2</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">20.2 Name Scopes</font></h2>
<font size="+1">

<dl>
	<dt>Scope</dt>
	<dd>The part of a program where a name is visible and has meaning (sect.
		5.9)</dd>
</dl>

<p>Scopes we have seen:</p>

<ul>
	<dl>
		<dt>Block Scope</dt>
		<dd>Any block delimited by curly braces (<tt>{}</tt>).  Name is destroyed
			after the closing curly brace</dd>
		<dt>Local Scope</dt>
		<dd>Special case of block scope.  A function's local variables
			and formal parameters have meaning only inside that function</dd>
	</dl>
</ul>

</font>

<hr><h2><font color="#009999">20.2 Name Scopes (cont.)</font></h2>
<font size="+1">

<p>Scopes we have seen (cont.):</p>

<ul>
	<dl>
		<dt>Class Scope</dt>
		<dd><tt>private</tt> members of a class only have meaning to other members
			(and friends) of that class</dd>
		<dt>Global Scope</dt>
		<dd>Identifiers declared outside functions and classes</dd>
		<dd>From declaration until the end of file</dd>
		<dd>Visible in other files by declaring it as <tt>extern</tt></dd>
		<dt>File Scope</dt>
		<dd>A <tt>static</tt> <u>global</u> - "local" to file</dd>
	</dl>
</ul>

</font>

<hr><h2><font color="#009999">20.2 Name Scopes (cont.)</font></h2>
<font size="+1">

<p>Scopes may nest</p>

<blockquote>
<pre>int count = 0; <font color="#0000cc">// Create a global variable</font>
. . .
int count_items()
{
   int orig_count = count; <font color="#0000cc">// holds value in global variable</font>
   int count = 0; <font color="#0000cc">// A different variable named count</font>
   for (...)
      count++; <font color="#0000cc">// Increment the local variable</font>
   return count + orig_count;
}
<font color="#0000cc">// Local count and orig_count are no longer available,</font></pre>
</blockquote>

</font>

<hr><h2><font color="#009999">20.2.1 Shadows and Qualification</font></h2>
<font size="+1">

<ul>
	<li>A name can hide (or block) a name from an outer scope</li>
	<li>This name <i>shadows</i> the previous definition</li>
	<li>Name resumes its previous meaning when inner scope exits</li>
</ul>

</font>

<hr><h2><font color="#009999">20.2.1 Shadows and Qualification</font></h2>
<font size="+1">

<p>To access (some) hidden names:</p>

<ul>
	<li>Use <tt>this</tt> to get to hidden attributes (next slide)</li>
	<li>Use the unary scope <tt>::</tt> to access globals (next slide)</li>
	<li>Binary scope to get to another class' hidden names:
		<blockquote>
<pre>int TravelClock::get_hours() const
{
   int h = Clock::get_hours();
      <font color="#0000cc">// Qualify which get_hours is intended</font>
   . . .
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">20.2.1 Example</font></h2>
<font size="+1">

<p>Perverse example:</p>

<blockquote>
<pre><font color="#0000cc">// DONT WRITE CODE SUCH AS THIS!</font>
double balance; <font color="#0000cc">// balance has global scope</font>
class BankAccount
{
public:
   BankAccount(double balance);
      <font color="#0000cc">// Parameter variable balance has local scope</font>
private:
   double balance; <font color="#0000cc">// Data field balance has class scope</font>
};</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">20.2.1 Example (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>BankAccount::BankAccount(double balance)
{
   this-&gt;balance = balance;
      <font color="#0000cc">// Assign data field balance using parameter value</font>
   ::balance = balance;
      <font color="#0000cc">// Assign global variable using parameter value</font>
}</pre>
</blockquote>

<ul>
	<li><tt>balance</tt> member shadows the global</li>
	<li>C'tor's parameter shadows both the attribute and the global</li>
	<li>Don't need <tt>orig_count</tt></li>
</ul>

</font>

<hr><h2><font color="#009999">Advanced Topic 20.1</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">

<p><font color="#009999">Overriding, Shadowing, and Scopes</font></p>

<ul>
	<li>Overloading an inherited member function hides that function:
	</li>
</ul>

<blockquote>
<pre>class Employee
{  . . .
   virtual void set_salary(int new_salary);
};
class Manager : public Employee
{  . . .
   virtual void set_salary(int new_salary, int yearly_bonus);
};
Manager m;
m.set_salary(45000); <font color="#ff0000">// Error - requires 2 args</font></pre>
</blockquote>

</font>

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

<ul>
	<li>To fix:
 		<ul>
			<li>Override the function in the derived class</li>
			<li>call the base class' method explicitly</li>
		</ul>
	</li>
</ul>

<blockquote>
<pre>class Manager : public Employee
{
   . . .
   virtual void set_salary(int new_salary);
   void set_salary(int new_salary, int yearly_bonus);
};

void Manager::set_salary(int new_salary)
{
   Employee::set_salary(new_salary); <font color="#0000cc">// Invoke the base class function</font>
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">20.3 Protected Scope</font></h2>
<font size="+1">

<ul>
	<li>Derived class inherits <tt>private</tt> members, but can not access
		them</li>
	<li><tt>protected</tt> indicates members that only derived classes can
		access</li>
	<li>Example:  <tt>Chart</tt> stores data, derived classes <tt>PieChart</tt>,
		<tt>BarChart</tt>, etc. each display data in a different fashion:</li>
</ul>

</font>

<hr><h2><font color="#009999">20.3 Protected Scope (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>class Chart
{
public:
   virtual void draw() const;
   . . .
protected:
   vector<double> data;
};

class PieChart : public Chart
{
public:
   virtual void draw() const;
   . . .
};</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">20.3 Protected Scope (cont.)</font></h2>
<font size="+1">

<table border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.1:
			Protected Members</font>

<pre>class <i>ClassName</i>
{
	. . .
protected:
	<i>member functions and data fields</i>
};</pre>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
					<td><font size="+1">Declare member functions and data fields that are
						visible to derived classes.</font></td>
				</tr>
			</table>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">20.3 Protected Scope (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.1 (cont.)
			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>
					<td><font size="+1">

<pre>class Chart
{
	. . .
protected:
	vector&lt;double&gt; data;
	double value_at(int index) const;
};</pre>
						</font>
					</td>
				</tr>
			</table>
			</font>
		</td>
	</tr>
</table>

<ul>
	<li>Classes now have three interfaces</li>
	<li><font color="#009999">Tip:</font>  Use protected methods to access
		private data</li>
</ul>

</font>

<hr><h2><font color="#009999">20.4 Friends</font></h2>
<font size="+1">

<ul>
	<li>Grants access to non-public members to another function or non-derived
		class</li>
	<li>Declare other entity as a <i>friend</i> in class definition</li>
	<li>Each friend must be explicitly named</li>
	<li>Granting friendship to a class grants access to all of its member
		functions</li>
	<li>Still dangerous, but more precise mechanism</li>
</ul>

</font>

<hr><h2><font color="#009999">20.4 Friends (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Refer to section 16.2.1:
		<blockquote>
<pre>class Node
{
public:
   Node(string s);
private:
   string data;
   Node* previous;
   Node* next;
<font color="#009999">friend class List;
friend class Iterator;</font>
};</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">20.4 Friends (cont.)</font></h2>
<font size="+1">

<ul>
		<ul>
			<li>Only <tt>List</tt> and <tt>Iterator</tt> are allowed to view and
				modify data fields of <tt>Node</tt></li>
		</ul>
	<li>Friendship is granted, not taken</li>
	<li>Friend functions are <i>not</i> member functions</li>
	<li>Access modifier is irrelevant</li>
	<li>Friendship is <i>not</i> symmetric</li>
</ul>

</font>

<hr><h2><font color="#009999">20.4 Friend - 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.2:
		Friends</font>

<pre>class <i>ClassName</i>
{
	. . .
	<font color="#009999">friend class <i>ClassName</i>;
	friend <i>return_type function_name(parameter list)</i>;</font>
}</pre>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">Purpose:</font></td>
					<td><font size="+1">Allow other classes and functions access to
					private features of a class.</font></td>
				</tr>
			</table>

		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">20.4 Friend - syntax (cont.)</font></h2>
<font size="+1">

<table width='100%' border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1">
			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>
					<td valign='top'><font size="+1">

<pre>class Node
{
public:
   Node(string s);
private:
   string data;
   Node* previous;
   Node* next;
<font color="#009999">friend class List;
friend class Iterator;</font>
};
class Employee
{
   . . .
   <font color="#009999">friend ostream&amp; operator&lt;&lt;(ostream&amp; out,
      const Employee&amp; e)</font>
};</pre>
						</font>
					</td>
				</tr>
			</table>
			</font>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">20.4 Friends & Streams</font></h2>
<font size="+1">

<p>Example:  <tt>stream</tt> operators:</p>
	<blockquote>
<pre>class Employee
{
public:
   Employee(string employee_name, double initial_salary);
   . . .
private:
   string name;
   double salary;
   <font color="#009999">friend ostream&amp; operator&lt;&lt;(ostream&amp; out, const Employee&amp; e);</font>
};</pre>
	</blockquote>

</font>

<hr><h2><font color="#009999">20.4 Friends & Streams (cont.)</font></h2>
<font size="+1">

<blockquote>
<pre>ostream&amp; operator&lt;&lt;(ostream&amp; out, const Employee&amp; e)
{
   out &lt;&lt; "Employee: " &lt;&lt; e.name;
   return out;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">20.5 Nested Classes</font></h2>
<font size="+1">

<ul>
	<li>Compare our <tt>Iterator</tt> (chptr. 16):
		<blockquote><tt>
			Iterator pos = staff.begin();
		</tt></blockquote>
	</li>
	<li>to the STL <tt>iterator</tt>:
		<blockquote><tt>
			list&lt;string&gt;::iterator pos = staff.begin();
		</tt></blockquote>
	</li>
	<li><tt>iterator</tt> is <i>nested</i> inside the <tt>list</tt>
		class</li>
	<li>Allows other containers to define their own iterators with different
		behaviors</li>
</ul>

</font>

<hr><h2><font color="#009999">20.5 Nested Classes (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Have the same interfaces</li>
	<li>Share names, but not in the same namespace</li>
	<li>Expressed with a qualified name:
		<blockquote><tt>
			vector&lt;double&gt;::iterator p = a.begin();<br>
			list&lt;string&gt;::iterator q = b.begin();
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">20.5 Nested Classes - syntax</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.3:
			Nested Class Declaration</font>

<pre>class <i>OuterClassName</i>
{
   . . .
   class <i>NestedClassName</i>;
   . . .
};</pre>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">20.5 Nested Classes - syntax (cont.)</font></h2>
<font size="+1">

<table border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 20.3:
			Nested Class Declaration (cont.)</font>

			<table border="0" cellpadding="4">

⌨️ 快捷键说明

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