📄 ch12.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<!-- This document was created from RTF source by rtftohtml version 3.0.1 -->
<META NAME="GENERATOR" Content="Symantec Visual Page 1.0">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<TITLE>Teach Yourself C++ in 21 Days</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">
<H1 ALIGN="CENTER"><A HREF="ch11.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/htm/ch11.htm"><IMG SRC="BLANPREV.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANPREV.GIF"
WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="tppmsgs/msgs0.htm#1" tppabs="http://www.mcp.com/sams"><IMG
SRC="BLANHOME.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANHOME.GIF" WIDTH="37" HEIGHT="37" ALIGN="BOTTOM"
BORDER="0"></A><A HREF="index.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/index.htm"><IMG SRC="BLANTOC.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANTOC.GIF"
WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="ch13.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/htm/ch13.htm"><IMG SRC="BLANNEXT.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANNEXT.GIF"
WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A></H1>
<H1></H1>
<UL>
<LI><A HREF="#Heading1">Day 12</A>
<UL>
<LI><A HREF="#Heading2">Inheritance</A>
<UL>
<LI><A HREF="#Heading3">What Is Inheritance?</A>
<UL>
<LI><A HREF="#Heading4">Inheritance and Derivation</A>
<UL>
<LI><A HREF="#Heading5">Figure 12.1.</A>
</UL>
<LI><A HREF="#Heading6">The Animal Kingdom</A>
<LI><A HREF="#Heading7">The Syntax of Derivation</A>
</UL>
<LI><A HREF="#Heading8">Listing 12.1. Simple inheritance</A><A HREF="#Heading9">.</A>
<LI><A HREF="#Heading10">Private Versus Protected</A>
<LI><A HREF="#Heading11">Listing 12.2. Using a derived object</A><A HREF="#Heading12">.</A>
<LI><A HREF="#Heading13">Constructors and Destructors</A>
<LI><A HREF="#Heading14">Listing 12.3. Constructors and destructors called</A><A
HREF="#Heading15">.</A>
<UL>
<LI><A HREF="#Heading16">Passing Arguments to Base Constructors</A>
</UL>
<LI><A HREF="#Heading17">Listing 12.4. Overloading constructors in derived classes</A><A
HREF="#Heading18">.</A>
<LI><A HREF="#Heading19">Overriding Functions</A>
<LI><A HREF="#Heading20">Listing 12.5. Overriding a base class method</A>
<LI><A HREF="#Heading21">in a derived class.</A>
<LI><A HREF="#Heading22">Overloading Versus Overriding</A>
<UL>
<LI><A HREF="#Heading23">Hiding the Base Class Method</A>
</UL>
<LI><A HREF="#Heading24">Listing 12.6. Hiding methods</A><A HREF="#Heading25">.</A>
<LI><A HREF="#Heading26">Overriding Versus Hiding</A>
<UL>
<LI><A HREF="#Heading27">Calling the Base Method</A>
</UL>
<LI><A HREF="#Heading28">Listing 12.7. Calling base method from overridden method</A><A
HREF="#Heading29">.</A>
<LI><A HREF="#Heading30">Virtual Methods</A>
<LI><A HREF="#Heading31">Listing 12.8. Using virtual methods</A><A HREF="#Heading32">.</A>
<LI><A HREF="#Heading33">Listing 12.9. Multiple virtual functions called in turn</A><A
HREF="#Heading34">.</A>
<UL>
<LI><A HREF="#Heading35">How Virtual Functions Work</A>
<UL>
<LI><A HREF="#Heading36">Figure 12.2.</A>
<LI><A HREF="#Heading37">Figure 12.3.</A>
<LI><A HREF="#Heading38">Figure 12.4.</A>
</UL>
<LI><A HREF="#Heading39">You Cant Get There from Here</A>
<LI><A HREF="#Heading40">Slicing</A>
</UL>
<LI><A HREF="#Heading41">Listing 12.10. Data slicing when passing by value</A><A
HREF="#Heading42">.</A>
<UL>
<LI><A HREF="#Heading43">Virtual Destructors</A>
<LI><A HREF="#Heading44">Virtual Copy Constructors</A>
</UL>
<LI><A HREF="#Heading45">Listing 12.11. Virtual copy constructor</A><A HREF="#Heading46">.</A>
<UL>
<LI><A HREF="#Heading47">The Cost of Virtual Methods</A>
</UL>
<LI><A HREF="#Heading48">Summary</A>
<LI><A HREF="#Heading49">Q&A</A>
<LI><A HREF="#Heading50">Workshop</A>
<UL>
<LI><A HREF="#Heading51">Quiz</A>
<LI><A HREF="#Heading52">Exercises</A>
</UL>
</UL>
</UL>
</UL>
<P>
<HR SIZE="4">
<H2 ALIGN="CENTER"><A NAME="Heading1"></A><FONT COLOR="#000077">Day 12</FONT></H2>
<H2 ALIGN="CENTER"><A NAME="Heading2"></A><FONT COLOR="#000077">Inheritance</FONT></H2>
<P>It is a fundamental aspect of human intelligence to seek out, recognize, and create
relationships among concepts. We build hierarchies, matrices, networks, and other
interrelationships to explain and understand the ways in which things interact. C++
attempts to capture this in inheritance hierarchies. Today you will learn
<UL>
<LI>What inheritance is.
<P>
<LI>How to derive one class from another.
<P>
<LI>What protected access is and how to use it.
<P>
<LI>What virtual functions are.
</UL>
<H3 ALIGN="CENTER"><A NAME="Heading3"></A><FONT COLOR="#000077">What Is Inheritance?</FONT></H3>
<P>What is a dog? When you look at your pet, what do you see? A biologist sees a
network of interacting organs, a physicist sees atoms and forces at work, and a taxonomist
sees a representative of the species canine domesticus.</P>
<P>It is that last assessment that interests us at the moment. A dog is a kind of
canine, a canine is a kind of mammal, and so forth. Taxonomists divide the world
of living things into Kingdom, Phylum, Class, Order, Family, Genus, and Species.</P>
<P>This hierarchy establishes an is-a relationship. A dog is a kind of canine. We
see this relationship everywhere: A Toyota is a kind of car, which is a kind of vehicle.
A sundae is a kind of dessert, which is a kind of food.</P>
<P>What do we mean when we say something is a kind of something else? We mean that
it is a specialization of that thing. That is, a car is a special kind of vehicle.
<H4 ALIGN="CENTER"><A NAME="Heading4"></A><FONT COLOR="#000077">Inheritance and Derivation</FONT></H4>
<P>The concept dog inherits, that is, it automatically gets, all the features of
a mammal. Because it is a mammal, we know that it moves and that it breathes air--all
mammals move and breathe air by definition. The concept of a dog adds the idea of
barking, wagging its tail, and so forth to that definition. We can further divide
dogs into hunting dogs and terriers, and we can divide terriers into Yorkshire Terriers,
Dandie Dinmont Terriers, and so forth.</P>
<P>A Yorkshire Terrier is a kind of terrier, therefore it is a kind of dog, therefore
a kind of mammal, therefore a kind of animal, and therefore a kind of living thing.
This hierarchy is represented in Figure 12.1.<BR>
<BR>
<A NAME="Heading5"></A><A HREF="12zcp01.jpg" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/art/ch12/12zcp01.jpg"><FONT COLOR="#000077">Figure
12.1.</FONT></A><I>Hierarchy of <TT>Animal</TT>s. </I><BR>
<BR>
C++ attempts to represent these relationships by enabling you to define classes that
derive from one another. Derivation is a way of expressing the is-a relationship.
You derive a new class, <TT>Dog</TT>, from the class <TT>Mammal</TT>. You don't have
to state explicitly that dogs move, because they inherit that from <TT>Mammal</TT>.</P>
<DL>
<DD>
<HR>
<FONT COLOR="#000077"><B>New Term:</B></FONT><B> </B>A class which adds new functionality
to an existing class is said to <I>derive </I>from that original class. The original
class is said to be the new class's base class.
<HR>
</DL>
<P>If the <TT>Dog</TT> class derives from the <TT>Mammal</TT> class, then <TT>Mammal</TT>
is a base class of <TT>Dog</TT>. Derived classes are supersets of their base classes.
Just as dog adds certain features to the idea of mammal, the <TT>Dog</TT> class will
add certain methods or data to the <TT>Mammal</TT> class.</P>
<P>Typically, a base class will have more than one derived class. Just as dogs, cats,
and horses are all types of mammals, their classes would all derive from the <TT>Mammal</TT>
class.
<H4 ALIGN="CENTER"><A NAME="Heading6"></A><FONT COLOR="#000077">The Animal Kingdom</FONT></H4>
<P>To facilitate the discussion of derivation and inheritance, this chapter will
focus on the relationships among a number of classes representing animals. You can
imagine that you have been asked to design a children's game--a simulation of a farm.</P>
<P>In time you will develop a whole set of farm animals, including horses, cows,
dogs, cats, sheep, and so forth. You will create methods for these classes so that
they can act in the ways the child might expect, but for now you'll stub-out each
method with a simple <TT>print</TT> statement.</P>
<P>Stubbing-out a function means you'll write only enough to show that the function
was called, leaving the details for later when you have more time. Please feel free
to extend the minimal code provided in this chapter to enable the animals to act
more realistically.
<H4 ALIGN="CENTER"><A NAME="Heading7"></A><FONT COLOR="#000077">The Syntax of Derivation</FONT></H4>
<P>When you declare a class, you can indicate what class it derives from by writing
a colon after the class name, the type of derivation (public or otherwise), and the
class from which it derives. The following is an example.</P>
<PRE><FONT COLOR="#0066FF">class Dog : public Mammal
</FONT></PRE>
<P>The type of derivation will be discussed later in this chapter. For now, always
use <TT>public</TT>. The class from which you derive must have been declared earlier,
or you will get a compiler error. Listing 12.1 illustrates how to declare a <TT>Dog</TT>
class that is derived from a <TT>Mammal</TT> class.</P>
<P><A NAME="Heading8"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 12.1. Simple
inheritance.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1: //Listing 12.1 Simple inheritance
2:
3: #include <iostream.h>
4: enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
5:
6: class Mammal
7: {
8: public:
9: // constructors
10: Mammal();
11: ~Mammal();
12:
13: //accessors
14: int GetAge()const;
15: void SetAge(int);
16: int GetWeight() const;
17: void SetWeight();
18:
19: //Other methods
20: void Speak();
21: void Sleep();
22:
23:
24: protected:
25: int itsAge;
26: int itsWeight;
27: };
28:
29: class Dog : public Mammal
30: {
31: public:
32:
33: // Constructors
34: Dog();
35: ~Dog();
36:
37: // Accessors
38: BREED GetBreed() const;
39: void SetBreed(BREED);
40:
41: // Other methods
42: // WagTail();
43: // BegForFood();
44:
45: protected:
46: BREED itsBreed;
<TT>47: };</TT></FONT></PRE>
<P><TT><BR>
</TT>This program has no output because it is only a set of class declarations without
their implementations. Nonetheless, there is much to see here.</P>
<P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On lines 6-27, the <TT>Mammal</TT>
class is declared. Note that in this example, <TT>Mammal</TT> does not derive from
any other class. In the real world, mammals do derive--that is, mammals are kinds
of animals. In a C++ program, you can represent only a fraction of the information
you have about any given object. Reality is far too complex to capture all of it,
so every C++ hierarchy is an arbitrary representation of the data available. The
trick of good design is to represent the areas that you care about in a way that
maps back to reality in a reasonably faithful manner.</P>
<P>The hierarchy has to begin somewhere; this program begins with <TT>Mammal</TT>.
Because of this decision, some member variables that might properly belong in a higher
base class are now represented here. For example, certainly all animals have an age
and weight, so if <TT>Mammal</TT> is derived from <TT>Animal</TT>, we might expect
to inherit those attributes. As it is, the attributes appear in the <TT>Mammal</TT>
class.</P>
<P>To keep the program reasonably simple and manageable, only six methods have been
put in the <TT>Mammal</TT> class--four accessor methods, <TT>Speak()</TT>, and <TT>Sleep()</TT>.</P>
<P>The <TT>Dog</TT> class inherits from <TT>Mammal</TT>, as indicated on line 29.
Every <TT>Dog</TT> object will have three member variables: <TT>itsAge</TT>, <TT>itsWeight</TT>,
and <TT>itsBreed</TT>. Note that the class declaration for <TT>Dog</TT> does not
include the member variables <TT>itsAge</TT> and <TT>itsWeight</TT>. <TT>Dog</TT>
objects inherit these variables from the <TT>Mammal</TT> class, along with all of
<TT>Mammal</TT>'s methods except the copy operator and the constructors and destructor.
<H3 ALIGN="CENTER"><A NAME="Heading10"></A><FONT COLOR="#000077">Private Versus Protected</FONT></H3>
<P>You may have noticed that a new access keyword, <TT>protected</TT>, has been introduced
on lines 24 and 45 of Listing 12.1. Previously, class data had been declared <TT>private</TT>.
However, <TT>private</TT> members are not available to derived classes. You could
make <TT>itsAge</TT> and <TT>itsWeight</TT> public, but that is not desirable. You
don't want other classes accessing these data members directly.</P>
<P>What you want is a designation that says, "Make these visible to this class
and to classes that derive from this class." That designation is protected.
Protected data members and functions are fully visible to derived classes, but are
otherwise private.</P>
<P>There are, in total, three access specifiers: public, protected, and private.
If a function has an object of your class, it can access all the public member data
and functions. The member functions, in turn, can access all private data members
and functions of their own class, and all protected data members and functions of
any class from which they derive.</P>
<P>Thus, the function <TT>Dog::WagTail()</TT> can access the private data <TT>itsBreed</TT>
and can access the protected data in the <TT>Mammal</TT> class.</P>
<P>Even if other classes are layered between <TT>Mammal</TT> and <TT>Dog</TT> (for
example, <TT>DomesticAnimals</TT>), the <TT>Dog</TT> class will still be able to
access the protected members of <TT>Mammal</TT>, assuming that these other classes
all use public inheritance. Private inheritance is discussed on Day 15, "Advanced
Inheritance."</P>
<P>Listing 12.2 demonstrates how to create objects of type <TT>Dog</TT> and access
the data and functions of that type.</P>
<P><A NAME="Heading11"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 12.2. Using
a derived object.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1: //Listing 12.2 Using a derived object
2:
3: #include <iostream.h>
4: enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };
5:
6: class Mammal
7: {
8: public:
9: // constructors
10: Mammal():itsAge(2), itsWeight(5){}
11: ~Mammal(){}
12:
13: //accessors
14: int GetAge()const { return itsAge; }
15: void SetAge(int age) { itsAge = age; }
16: int GetWeight() const { return itsWeight; }
17: void SetWeight(int weight) { itsWeight = weight; }
18:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -