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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<!--	-*-html-*-
	$Source: /usr/local/cvsroot/BigC++/21/index.html,v $
	$Revision: 1.6 $
	Big C++, chptr 21
	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:
	- $Log: index.html,v $
	- Revision 1.6  2004/04/20 22:02:58  kurt
	- Made slides smaller (view %150, on 1024x768 display)
	-
	- Revision 1.5  2004/02/23 04:44:45  kurt
	- linked in images, cribbed verbage
	-
	- Revision 1.4  2004/02/03 02:45:56  kurt
	- Pared language, split slides
	-
	- Revision 1.3  2004/01/21 13:34:14  kurt
	- fixed spelling
	-
	- Revision 1.2  2004/01/20 06:03:19  kurt
	- first pass
	-
	- Revision 1.1  2004/01/20 03:16:48  kurt
	- Creation
-->

<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>

<hr><h2><font color="#009999" size="+3">Chapter 21 - Polymorphism</font></h2>
<font size="+1">

<script><!-- // Set title on page
	image( "cover.png" )
//--></script>

</font>

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

<ul>
	<li>To be able to describe the information conveyed by a class hierarchy</li>
	<li>To understand the concept of the polymorphic variable and its relationship
	to class hierarchies</li>
	<li>To understand the interaction between polymorphism and memory
	management</li>
	<li>To understand how to distinguish between virtual and nonvirtual overriding
	and the uses of each</li>
	<li>To understand the concept of downcasting, moving both up and down the
	class hierarchy</li>
	<li>To understand the concept of multiple inheritance</li>
	<li>To learn how to design and use software frameworks</li>
</ul>

</font>

<hr><h2><font color="#009999">21.1 Class Inheritance Hierarchies</font></h2>
<font size="+1">

<ul>
	<li>Hierarchies often used to categorize concepts</li>
	<li>Often represented using trees:
		<script><!--
			image( "fig01.png" )
		//--></script>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.1 Class Inheritance Hierarchies (cont.)
	</font></h2>
<font size="+1">

<ul>
	<li>The class inheritance relationship (is-a) fits this pattern</li>
	<li>Base classes at the top, derived classes below</li>
	<li>Each level linked to the object above by a <i>is-a</i> relationship</li>
	<li>Each derived class is more specialized</li>
</ul>

</font>

<hr><h2><font color="#009999">21.1 Class Inheritance Hierarchies
	(cont.)</font></h2>
<font size="+1">

<ul>
	<li>Some hierarchies are short:</li>
</ul>

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

<ul>
	<li>Forest vs. Tree</li>
</ul>

</font>

<hr><h2><font color="#009999">21.1 Class Inheritance Hierarchies
	(cont.)</font></h2>
<font size="+1">

<ul>
	<li>Others can be complex:</li>
</ul>	

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

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables</font></h2>
<font size="+1">

<ul>
	<li>Powerful mechanism in the OO paradigm</li>
	<li>Polymorphic - many forms</li>
	<li>Consider our <tt>Employee</tt> class:
		<ul>
			<li>add <tt>annual_income</tt> method</li>
			<li>for <tt>Employee</tt>, this is equal to their yearly salary</li>
			<li>inherit <tt>Manager</tt> from <tt>Employee</tt></li>
			<li>a <tt>Manager's</tt> annual income is the sum of their salary
			and bonus</li>
		</ul>
		(Code on next slide)
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables - example</font></h2>
<font size="+1">

<blockquote>
<pre>class Employee
{
public:
   Employee(string n, double s);
   string get_name() const;
   double get_salary() const;
   void set_salary(double s);
   virtual double annual_income() const;
   void print(ostream&amp; out) const;
private:
   string name;
   double salary;
};</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables - example (cont.)
	</font></h2>
<font size="+1">

<blockquote>
<pre>double Employee::annual_income() const
{
   return get_salary();
}</pre>

<pre>class Manager : public Employee
{
public:
   Manager(string n, double s, double b);
   virtual double annual_income() const;
private:
   double bonus;
};</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables - example (cont.)
	</font></h2>
<font size="+1">

<blockquote>
<pre>Manager::Manager(string n, double s, double b)
   : Employee(n, s), bonus(b) {}

double Manager::annual_income() const
{
   return get_salary() + bonus;
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Pointer or reference declared with one type</li>
	<li>May hold a variable of a derived type:
		<blockquote><tt>
			Employee* emp = new Manager("Sarah Smith", 67000, 2000);
		</tt></blockquote>
		<ul>
			<li><tt>Employee*</tt> is the <i>static type</i></li>
			<li><tt>Manager*</tt> is the <i>dynamic type</i></li>
		</ul>
	</li>
	<li>Dynamic type determined at run time</li>
		<ul>
			<li>Can change during execution</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables - Dynamic
	Binding</font></h2>
<font size="+1">

<ul>
	<li>Power lies with dynamic binding</li>
	<li>A method invoked via polymorphic variable might execute the method
		of the dynamic type</li>
	<li>If the type changes during execution, so might the method selected</li>
</ul>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables - Dynamic
	Binding</font></h2>
<font size="+1">

<ul>
	<li>E.g., store members of a department in a vector of <tt>Employee</tt>
		pointers:
		<blockquote><tt>
			vector&lt;Employee*&gt; department(3);<br>
			department[0] = new Manager("Sarah Smith", 67000, 2000);<br>
			department[1] = new Employee("Lisa Lim", 36000);<br>
			department[2] = new Employee("Harry Hacker", 42000);
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.2 Polymorphic Variables - Dynamic
	Binding (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Print out information regarding each employee:
		<blockquote>
<pre>for (int i = 0; i &lt; department.size(); i++)
{
   cout &lt;&lt; "Employee: "
      &lt;&lt; department[i]-&gt;get_name() &lt;&lt; " income "
      &lt;&lt; department[i]-&gt;annual_income() &lt;&lt; "\n";
}</pre>
		</blockquote>
	</li>
	<li>Different <tt>annual_income</tt>s are being called:
		<blockquote><tt>
			Employee Sarah Smith income 69000<br>
			Employee Lisa Lim income 36000<br>
			Employee Harry Hacker income 42000
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.3 Virtual and Nonvirtual Overriding</font></h2>
<font size="+1">

<ul>
	<li>Override method in derived class</li>
	<li>Which method to execute:
		<ul>
			<li><i>statically bound</i> - invoked through a static type</li>
			<li><i>dynamically bound</i> - invoked through a dynamic type</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.3 Virtual and Nonvirtual Overriding
	(cont.)</font></h2>
<font size="+1">

<ul>
	<li>If an <i>object</i> invokes an operation, statically bound:
		<blockquote><tt>
			Employee e("Lisa Lim", 36000);<br>
			cout &lt;&lt; e.annual_income() &lt;&lt; "\n"; <font color="#0000cc">// Statically bound</font>
		</tt></blockquote>
	</li>
	<li>If a <i>virtual</i> method is invoked through a <i>pointer</i> or a
	<i>reference</i>, it is bound dynamically:
		<blockquote><tt>
			Employee* e = new Manager("Sarah Smith", 67000, 2000);<br>
			cout &lt;&lt; <font color="#009999">e-&gt;get_salary()</font>
				&lt;&lt; "\n";<br>
			<font color="#0000cc">
				// Static binding, because get_salary is not virtual</font><br>
			cout &lt;&lt; <font color="#009999">e-&gt;annual_income()</font>
				&lt;&lt; "\n";<br>
			<font color="#0000cc">
				// Dynamic binding, because annual_income is virtual</font>
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.3 Virtual and Nonvirtual Overriding
	(cont.)</font></h2>
<font size="+1">

<ul>
	<li>Methods invoked via <tt>this</tt> ptr follow same rules:
		<blockquote>
<pre>void Employee::print(ostream&amp; out) const
{
   out &lt;&lt; "Name " &lt;&lt; get_name()
   <font color="#0000cc">// Static binding, same as Employee::get_name()</font>
      &lt;&lt; " income " &lt;&lt; annual_income() &lt;&lt; "\n";
      <font color="#0000cc">// Dynamic binding, same as this->annual_income()</font>
}</pre>
		</blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">21.3 Virtual and Nonvirtual Overriding
	(cont.)</font></h2>
<font size="+1">

<ul>
	<li>The use of the dynamic type applies only to the <i>selector</i> of
		a member function</li>
	<li>Dynamic types of arguments are <i>not</i> considered in determination
		of a function for execution:</li>
</ul>

</font>

<hr><h2><font color="#009999">21.3 Virtual and Nonvirtual Overriding
	(cont.)</font></h2>
<font size="+1">

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

ostream&amp; operator&lt;&lt;(ostream&amp; out, const Manager&amp; m)
{
   out &lt;&lt; "Manager " &lt;&lt; e.name();
   return out;
}

Manager man = new Manager(. . .);
cout &lt;&lt; *man &lt;&lt; "\n"; <font color="#0000cc">// Executes Manager function</font></pre>
	</blockquote>
</ul>

</font>

<hr><h2><font color="#009999">21.3 Virtual and Nonvirtual Overriding
	(cont.)</font></h2>
<font size="+1">

<ul>
	<li>Passing an instance of a derived class might be confusing:
		<blockquote>
<pre>void print(ostream&amp; out, Employee&amp; emp)
{
   out &lt;&lt; emp &lt;&lt; "\n";
}

print(cout, *man);
   <font color="#0000cc">// Will print name as Employee not as Manager</font></pre>
		</blockquote>
	</li>
	<li><tt>emp</tt>'s static type (<tt>Employee</tt>) is used to choose 
		<tt>operator&lt;&lt;</tt></li>
	<li>Try restructuring the flow of control (next slide):</li>
</ul>

⌨️ 快捷键说明

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