📄 ch12.htm
字号:
19: //Other methods
20: 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: };
28:
29: class Dog : public Mammal
30: {
31: public:
32:
33: // Constructors
34: Dog():itsBreed(YORKIE){}
35: ~Dog(){}
36:
37: // Accessors
38: BREED GetBreed() const { return itsBreed; }
39: void SetBreed(BREED breed) { itsBreed = breed; }
40:
41: // Other methods
42: void WagTail() { cout << "Tail wagging...\n"; }
43: void BegForFood() { cout << "Begging for food...\n"; }
44:
45: private:
46: BREED itsBreed;
47: };
48:
49: int main()
50: {
51: Dog fido;
52: fido.Speak();
53: fido.WagTail();
54: cout << "Fido is " << fido.GetAge() << " years old\n";
55: return 0;
<TT>56: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: Mammal sound!
Tail wagging...
Fido is 2 years old
</FONT></PRE>
<P><FONT COLOR="#000077"><B><BR>
Analysis:</B></FONT><B> </B>On lines 6-27, the <TT>Mammal</TT> class is declared
(all of its functions are inline to save space here). On lines 29-47, the <TT>Dog</TT>
class is declared as a derived class of <TT>Mammal</TT>. Thus, by these declarations,
all <TT>Dog</TT>s have an age, a weight, and a breed.</P>
<P>On line 51, a <TT>Dog</TT> is declared: <TT>Fido</TT>. <TT>Fido</TT> inherits
all the attributes of a <TT>Mammal</TT>, as well as all the attributes of a <TT>Dog</TT>.
Thus, <TT>Fido</TT> knows how to <TT>WagTail()</TT>, but also knows how to <TT>Speak()</TT>
and <TT>Sleep()</TT>.
<H3 ALIGN="CENTER"><A NAME="Heading13"></A><FONT COLOR="#000077">Constructors and
Destructors</FONT></H3>
<P><TT>Dog</TT> objects are <TT>Mammal</TT> objects. This is the essence of the is-a
relationship. When <TT>Fido</TT> is created, his base constructor is called first,
creating a <TT>Mammal</TT>. Then the <TT>Dog</TT> constructor is called, completing
the construction of the <TT>Dog</TT> object. Because we gave <TT>Fido</TT> no parameters,
the default constructor was called in each case. <TT>Fido</TT> doesn't exist until
he is completely constructed, which means that both his <TT>Mammal</TT> part and
his <TT>Dog</TT> part must be constructed. Thus, both constructors must be called.</P>
<P>When <TT>Fido</TT> is destroyed, first the <TT>Dog</TT> destructor will be called
and then the destructor for the <TT>Mammal</TT> part of <TT>Fido</TT>. Each destructor
is given an opportunity to clean up after its own part of <TT>Fido</TT>. Remember
to clean up after your <TT>Dog</TT>! Listing 12.3 demonstrates this.</P>
<P><A NAME="Heading14"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 12.3. Constructors
and destructors called.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1: //Listing 12.3 Constructors and destructors called.
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 { 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 methods
20: 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: };
28:
29: class Dog : public Mammal
30: {
31: public:
32:
33: // Constructors
34: Dog();
35: ~Dog();
36:
37: // Accessors
38: BREED GetBreed() const { return itsBreed; }
39: void SetBreed(BREED breed) { itsBreed = breed; }
40:
41: // Other methods
42: void WagTail() { cout << "Tail wagging...\n"; }
43: void BegForFood() { cout << "Begging for food...\n"; }
44:
45: private:
46: BREED itsBreed;
47: };
48:
49: Mammal::Mammal():
50: itsAge(1),
51: itsWeight(5)
52: {
53: cout << "Mammal constructor...\n";
54: }
55:
56: Mammal::~Mammal()
57: {
58: cout << "Mammal destructor...\n";
59: }
60:
61: Dog::Dog():
62: itsBreed(YORKIE)
63: {
64: cout << "Dog constructor...\n";
65: }
66:
67: Dog::~Dog()
68: {
69: cout << "Dog destructor...\n";
70: }
71: int main()
72: {
73: Dog fido;
74: fido.Speak();
75: fido.WagTail();
76: cout << "Fido is " << fido.GetAge() << " years old\n";
77: return 0;
<TT>78: }</TT></FONT>
<FONT COLOR="#0066FF">
Output: Mammal constructor...
Dog constructor...
Mammal sound!
Tail wagging...
Fido is 1 years old
Dog destructor...
Mammal destructor...
</FONT></PRE>
<P><FONT COLOR="#000077"><B><BR>
Analysis:</B></FONT><B> </B>Listing 12.3 is just like Listing 12.2, except that the
constructors and destructors now print to the screen when called. <TT>Mammal</TT>'s
constructor is called, then <TT>Dog</TT>'s. At that point the <TT>Dog</TT> fully
exists, and its methods can be called. When <TT>fido</TT> goes out of scope, <TT>Dog</TT>'s
destructor is called, followed by a call to <TT>Mammal</TT>'s destructor.
<H4 ALIGN="CENTER"><A NAME="Heading16"></A><FONT COLOR="#000077">Passing Arguments
to Base Constructors</FONT></H4>
<P>It is possible that you'll want to overload the constructor of <TT>Mammal</TT>
to take a specific age, and that you'll want to overload the <TT>Dog</TT> constructor
to take a breed. How do you get the age and weight parameters passed up to the right
constructor in <TT>Mammal</TT>? What if <TT>Dog</TT>s want to initialize weight but
<TT>Mammal</TT>s don't?</P>
<P>Base class initialization can be performed during class initialization by writing
the base class name, followed by the parameters expected by the base class. Listing
12.4 demonstrates this.</P>
<P><A NAME="Heading17"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 12.4. Overloading
constructors in derived classes.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">1: //Listing 12.4 Overloading constructors in derived classes
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(int age);
12: ~Mammal();
13:
14: //accessors
15: int GetAge() const { return itsAge; }
16: void SetAge(int age) { itsAge = age; }
17: int GetWeight() const { return itsWeight; }
18: void SetWeight(int weight) { itsWeight = weight; }
19:
20: //Other methods
21: void Speak() const { cout << "Mammal sound!\n"; }
22: void Sleep() const { cout << "shhh. I'm sleeping.\n"; }
23:
24:
25: protected:
26: int itsAge;
27: int itsWeight;
28: };
29:
30: class Dog : public Mammal
31: {
32: public:
33:
34: // Constructors
35: Dog();
36: Dog(int age);
37: Dog(int age, int weight);
38: Dog(int age, BREED breed);
39: Dog(int age, int weight, BREED breed);
40: ~Dog();
41:
42: // Accessors
43: BREED GetBreed() const { return itsBreed; }
44: void SetBreed(BREED breed) { itsBreed = breed; }
45:
46: // Other methods
47: void WagTail() { cout << "Tail wagging...\n"; }
48: void BegForFood() { cout << "Begging for food...\n"; }
49:
50: private:
51: BREED itsBreed;
52: };
53:
54: Mammal::Mammal():
55: itsAge(1),
56: itsWeight(5)
57: {
58: cout << "Mammal constructor...\n";
59: }
60:
61: Mammal::Mammal(int age):
62: itsAge(age),
63: itsWeight(5)
64: {
65: cout << "Mammal(int) constructor...\n";
66: }
67:
68: Mammal::~Mammal()
69: {
70: cout << "Mammal destructor...\n";
71: }
72:
73: Dog::Dog():
74: Mammal(),
75: itsBreed(YORKIE)
76: {
77: cout << "Dog constructor...\n";
78: }
79:
80: Dog::Dog(int age):
81: Mammal(age),
82: itsBreed(YORKIE)
83: {
84: cout << "Dog(int) constructor...\n";
85: }
86:
87: Dog::Dog(int age, int weight):
88: Mammal(age),
89: itsBreed(YORKIE)
90: {
91: itsWeight = weight;
92: cout << "Dog(int, int) constructor...\n";
93: }
94:
95: Dog::Dog(int age, int weight, BREED breed):
96: Mammal(age),
97: itsBreed(breed)
98: {
99: itsWeight = weight;
100: cout << "Dog(int, int, BREED) constructor...\n";
101: }
102:
103: Dog::Dog(int age, BREED breed):
104: Mammal(age),
105: itsBreed(breed)
106: {
107: cout << "Dog(int, BREED) constructor...\n";
108: }
109:
110: Dog::~Dog()
111: {
112: cout << "Dog destructor...\n";
113: }
114: int main()
115: {
116: Dog fido;
117: Dog rover(5);
118: Dog buster(6,8);
119: Dog yorkie (3,YORKIE);
120: Dog dobbie (4,20,DOBERMAN);
121: fido.Speak();
122: rover.WagTail();
123: cout << "Yorkie is " << yorkie.GetAge() << " years old\n";
124: cout << "Dobbie weighs ";
125: cout << dobbie.GetWeight() << " pounds\n";
126: return 0;
<TT>127: }</TT></FONT></PRE>
<BLOCKQUOTE>
<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -