📄 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"><IMG SRC="../buttons/BLANPREV.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="http://www.mcp.com/sams"><IMGSRC="../buttons/BLANHOME.GIF" WIDTH="37" HEIGHT="37" ALIGN="BOTTOM"BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../buttons/BLANTOC.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="ch13.htm"><IMG SRC="../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 createrelationships among concepts. We build hierarchies, matrices, networks, and otherinterrelationships 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 anetwork of interacting organs, a physicist sees atoms and forces at work, and a taxonomistsees 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 ofcanine, a canine is a kind of mammal, and so forth. Taxonomists divide the worldof 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. Wesee 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 thatit 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 ofa mammal. Because it is a mammal, we know that it moves and that it breathes air--allmammals move and breathe air by definition. The concept of a dog adds the idea ofbarking, wagging its tail, and so forth to that definition. We can further dividedogs 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, thereforea 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="../art/ch12/12zcp01.jpg"><FONT COLOR="#000077">Figure12.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 thatderive 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 haveto 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 willadd 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 willfocus on the relationships among a number of classes representing animals. You canimagine 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 thatthey can act in the ways the child might expect, but for now you'll stub-out eachmethod with a simple <TT>print</TT> statement.</P><P>Stubbing-out a function means you'll write only enough to show that the functionwas called, leaving the details for later when you have more time. Please feel freeto extend the minimal code provided in this chapter to enable the animals to actmore 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 writinga colon after the class name, the type of derivation (public or otherwise), and theclass 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, alwaysuse <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. Simpleinheritance.</B></FONT></P><PRE><FONT COLOR="#0066FF">1: //Listing 12.1 Simple inheritance2:3: #include <iostream.h>4: enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };5:6: class Mammal7: {8: public:9: // constructors10: Mammal();11: ~Mammal();12:13: //accessors14: int GetAge()const;15: void SetAge(int);16: int GetWeight() const;17: void SetWeight();18:19: //Other methods20: void Speak();21: void Sleep();22:23:24: protected:25: int itsAge;26: int itsWeight;27: };28:29: class Dog : public Mammal30: {31: public:32:33: // Constructors34: Dog();35: ~Dog();36:37: // Accessors38: BREED GetBreed() const;39: void SetBreed(BREED);40:41: // Other methods42: // 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 withouttheir 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 fromany other class. In the real world, mammals do derive--that is, mammals are kindsof animals. In a C++ program, you can represent only a fraction of the informationyou 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. Thetrick of good design is to represent the areas that you care about in a way thatmaps 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 higherbase class are now represented here. For example, certainly all animals have an ageand weight, so if <TT>Mammal</TT> is derived from <TT>Animal</TT>, we might expectto 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 beenput 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 notinclude 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 introducedon 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 couldmake <TT>itsAge</TT> and <TT>itsWeight</TT> public, but that is not desirable. Youdon't want other classes accessing these data members directly.</P><P>What you want is a designation that says, "Make these visible to this classand to classes that derive from this class." That designation is protected.Protected data members and functions are fully visible to derived classes, but areotherwise 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 dataand functions. The member functions, in turn, can access all private data membersand functions of their own class, and all protected data members and functions ofany 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> (forexample, <TT>DomesticAnimals</TT>), the <TT>Dog</TT> class will still be able toaccess the protected members of <TT>Mammal</TT>, assuming that these other classesall use public inheritance. Private inheritance is discussed on Day 15, "AdvancedInheritance."</P><P>Listing 12.2 demonstrates how to create objects of type <TT>Dog</TT> and accessthe data and functions of that type.</P><P><A NAME="Heading11"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 12.2. Usinga derived object.</B></FONT></P><PRE><FONT COLOR="#0066FF">1: //Listing 12.2 Using a derived object2:3: #include <iostream.h>4: enum BREED { YORKIE, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };5:6: class Mammal7: {8: public:9: // constructors10: Mammal():itsAge(2), itsWeight(5){}11: ~Mammal(){}12:13: //accessors14: 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:19: //Other methods20: void Speak()const { cout << "Mammal sound!\n"; }21: void Sleep()const { cout << "shhh. I'm sleeping.\n"; }22:23:24: protected:25: int itsAge;26: int itsWeight;27: };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -