8.2.
;
.
, .
.
draw(), , ZooAnimal, Bear,
Panda, Cat Leopard. , draw(),
:
inline void draw( ZooAnimal& z )
{ z.draw(); }
draw() Panda,
z.draw() Panda::draw(). ,
Cat Cat::draw().
. ,
.
. ZooAnimal
, .
, ,
.
, .
QUIT, ZooAnimal
finalCollage(),
.
,
ZooAnimal .
,
ZooAnimal. finalCollage()
:
void finalCollage( ZooAnimal *pz )
{for ( ZooAnimal *p = pz; p
; p = p->next )
p->draw();}
,
,
, ZooAnimal. ,
isA() if-else switch,
isA(). finalCollage
:
// nonobject-oriented
implementation
void finalCollage( ZooAnimal *pz )
{ for ( ZooAnimal *p =
pz; p ; p = p->next )
switch ( p->isA() )
{ case BEAR:
((Bear *)
p)->draw();break;
case PANDA:((Panda *) p)->draw();break;// ... every
other derived class} //
switch of isA}
,
, .
,
.
, Panda .
, Koala.
if-else switch,
, .
.
switch
.
, .
.
,
, .
- , .
,
.
.
-. ,
, - .
.
ZooAnimal .
draw() ZooAnimal.
,
, header-
.
. ,
,
.
virtual. , ,
. virtual .
,
class Foo {public:virtual bar(); // virtual
declaration
};
int Foo::bar() { ... }
ZooAnimal : debug(), locate(),
draw() isOnDisplay().
#include <stream.h>
class
ZooAnimal
{
public:
ZooAnimal( char *whatIs = "ZooAnimal"): isA( whatIs
) {}
void isA()
{ cout << "nt" << isa << "n";
}
void setOpen( int status )
{ isOpen = status; }
virtual
isOnDisplay()
{ return isOpen; }
virtual void debug();
virtual void
draw() = 0;
protected:virtual void locate() = 0;
char *isa;
char
isOpen;
};
void ZooAnimal::debug()
{isA();cout <<
"tisOpen:"<< ((isOnDisplay()) ? "yes" :
"no") <<
"n";
}
debug(), locate(), draw() isOnDisplay()
ZooAnimal ,
. ,
, .
,
.
,
, , locate() draw().
ZooAnimal.
,
0 .
virtual void
draw() = 0;
virtual void locate() = 0;
draw() locate()
.
.
, .
, ZooAnimal
:
ZooAnimal *pz = new ZooAnimal; // error
ZooAnimal za; //
error
,
, .
,
,
.
- ,
,
.
- ,
,
. , Bear
draw() locate(),
.
, ,
Bear, draw()
Panda Grizzly ?
draw()
. :
1.
: class Bear :
public ZooAnimal {
public:void draw() {}// ...
};
2. ,
: void Bear::draw()
{ error( INTERNAL,
isa, "draw()" ); }
3. ,
Bear. ,
,
,
-.
.
, . , Bear
debug(), locate() draw(); isOnDisplay
ZooAnimal. Bear hibernates()
feedingHours(). Bear
.
class Bear :
{ public
ZooAnimal
public:Bear( char *whatIs = "Bear" ): ZooAnimal( whatIs
),
feedTime( "2:30" ) {} // intentionally null
void draw(); // replaces
ZooAnimal::draw
void locate(); // replaces ZooAnimal::locate
virtual char
*feedingHours()
{ return feedime; }
protectted:void debug(); // replaces
ZooAnimal::debug
virtual hibernates() { return 1; }
char
*feedTime;
};
,
. virtual
(, ).
.
void
Bear::debug()
{isA();cout << "tfeedTime:"
<< feedingHours()
<< "n";}
void Bear::draw() {/*...code goes here*/}
void
Bear::locate() {/*...code goes here*/}
.
virtual
.
, . ,
Bear debug() :
void *Bear::debug()
{...}// different return type
void Bear::debug( int ) {...}// different
signature
debug() Bear. ,
Bear
b;
ZooAnimal &za = b;
za.debug(); // invoke
ZooAnimal::debug()
Bear, ,
debug(), Bear .
,
class Panda : public Bear {
public:
void debug(); //
virtual instance
//
...
};
Panda
debug():
Panda
p;
ZooAnimal &za = p;
za.debug(); // Panda::debug()
,
. locate() ZooAnimal
protected, Bear public. , debug()
ZooAnimal public, Bear protected.
locate() debug()? ,
:
void debug( ZooAnimal& z )
{// compiler
resolves intended instance
z.debug();}
Bear::debug()
protected, ?
main()
{
// outputs :
Bear
// feedTime : 2.30
Bear ursus;
debug( ursus );}
: debug(ursus) .
,
. public, debug()
public ZooAnimal. , ,
, ZooAnimal
.
main()
{ ZooAnimal *pz = new Bear;
pz->debug(); //
invokes Bear::debug()
pz = new ZooAnimal;pz->setOpen(1); // open the
zoo
pz->debug(); // invokes ZooAnimal::debug() }
:
Bear
feedTime: 2:30
ZooAnimal
isOpen:
yes
debug() Bear,
, protected.
protected
:
main() {
ZooAnimal *pz = new Bear;
pz->debug(); // invokes
Bear::debug()
Bear *pb = (Bear *) new ZooAnimal;
// dangerous illegal :
main has no access privilege
// to the protected members of
Bear!
pb->debug();}
, locate() e protected
ZooAnimal public Bear.
Bear public .
ZooAnimal, ,
protected .
protected locate()
friend ZooAnimal.
void locate( ZooAnimal *pz )
{// locate()
has no access
privilege;// unless made friend to
ZooAnimal
pz->locate(); // error
}
,
,
,
. ,
, ,
.
Bear
, ZooAnimal;
. Panda ,
Bear.
ZooAnimal Bear? ,
ZooAnimal, . , debug()
:
void
Bear::debug()
{ZooAnimal::debug();
cout << "Fed time: "<<
feedTime << "n";}
Panda : Bear,
Endangered Herbivore. Endangered, Herbivore
:
class Endangered
{
public:
virtual adjustPopulation( int
);
virtual highlight( short ); //...
};
class
Herbivore
{
public:
virtual inform( ZooAnimal& );
virtual
highlight( short ); //...
};
Panda
, .
. ,
.
Panda ,
highlight() Endangered
Herbivore. highlight()
Panda Panda .
highlight() . ,
RedPanda
: public Panda { ... };
RedPanda pandy;
Panda &rp =
pandy;//...
rp.highlight(); // error : ambiguous
, Panda highlight() (
7.4). Panda
.
class Panda : public Bear, public Endangered,public
Herbivore
{
public:
Panda( char *whatIs = "Panda: ) : Bear( whatIs )
{}
virtual onLoan();
inform( ZooAnimal& );
void draw();
int
debug();
void locate();
hibernates() { return 0;
}
protected:
highlight( short );
short cell;
short
onLoan;
};
.
. ,
. , hibernate(),
Bear, ZooAnimal. , ,
:
int hibernate( ZooAnimal &za )
{
// error : hibernate
not a member of ZooAnimal
}
Bear
hibernate().
. hibernate()
, Bear.
hibernate() - (
ZooAnimal)
. hibernate()
, .
8.1
Panda.
, ; - ,
.
isOnDisplay() ZooAnimal locate()
Panda
ZooAnimal draw()
Panda ZooAnimal debug()
Panda ZooAnimal
feedingHours()
Bear Bear hibernates()
Bear
Bear
adjustPopulation(int)
Endangered
Endangered highlight(short)
Panda
Endangered/ Herbivore
Panda
inform(ZooAnimal&)
Herbivore
onLoan()
Panda Panda
8.1
Panda
.
.
.
8-1. ,
Bear, , . ?
? ?
8-2. 7.4
ZooAnimal, Bear Panda.
- ZooAnimal.
, X(
const X& ) operator = ( const X& ).
8-3.
debug() Shapes, 7.4
.
8-4.
debug(), 7.7
debug() Shapes.
8-5.
draw() Shapes.
8-6.
reSize() Shapes.
ZooAnimal,
finalCollage(), , .
for-loop finalCollage()
:
for ( ZooAnimal *p = pz->next; p;pz = p, p =
p->next )
delete pz;
. pz
ZooAnimal , pz. ZooAnimal,
Bear,
, .
,
.
for ( ZooAnimal *p
= pz->next; p;pz = p, p = p->next )
switch( pz->isA() )
{
case BEAR:// direct invocation of
destructor
((Bear*)pz)->Bear::~Bear();break;
case PANDA:// indirect
invocation through delete
delete (Panda *) pz;break;
//... more cses go
here
}
delete
. , :
.
8-7. Shapes
.
.
,
, :
- ,
-
, .
, ,
,
.
- ,
,
ZooAnimal. ZooAnimal
.
.
. ZooAnimal
- print() isA() -
.
#include <sstrea.h>
enum ZooLocs { ZOOANIMAL, BEAR,
PANDA };
class ZooAnimal
{
public:ZooAnimal( char *s = "ZooAnimal"
);
virtual ~ZooAnimal() { delete name; }
void link( ZooAnimal*
);
virtual void print( ostream& );
virtual void isA( ostream&
);
protected:
char *name;
ZooAnimal *next;
};
#include
<string.h>
ZooAnimal::ZooAnimal( char *s ) : next( 0 )
{
name =
new char[ strlen(s) + 1 ];
strcpy( name, s );
}
ZooAnimal, next.
;
.
link() ZooAnimal ZooAnimal*
next. :
void
ZooAnimal::link( ZooAnimal *za )
{
za->next = next;
next =
za;}
isA() print() .
. isA()
; print() .
ostream.
:
void ZooAnimal::isA( ostream& os )
{
os <<
"ZooAnimal name : "<< name << "n";}
void ZooAnimal::print(
osream& os )
{
isA( os ); // virtual invocation
}
- ,
ZooAnimal. ,
ZooAnimal.
:
#include
<stream.h>
ostream&
operator << ( ostream& os,
ZooAnimal& za )
{za.print( os );return os;}
ZooAnimal
print().
Bear Panda. ,
friend ZooAnimal.
friend
ZooAnimal. Bear
:
class Bear : public ZooAnimal
{
public:
Bear( char *s =
"Bear", ZooLocs loc = BEAR,char *sci = "Ursidae" );~
Bear() { delete sciName;
}
void print( ostream& );
void isA( ostream&
);
protected:
char *sciName; // scientific nameZooLocs
zooArea;
};
#include <string.h>
Bear::Bear( char *s, ZooLocs
loc, char *sci ) : ZooAnimal( s ), zooArea( loc )
{
sciName = new char[
strlen(sci) + 1 ]; strcpy( sciName, sci );
}
Bear
:* sciName, .*
zooArea, , .
isA() print() Bear .
:
void Bear::isA( ostream& os
)
{
ZooAnimal::isA( os ); // static invocation
os <<
"tscientific name:t";
os << sciName << "n";
}
static
char *locTable[] =
{
"The entire animal display area", //
ZOOANIMAL
"NorthWest : B1 : area Brown", // BEAR
"NorthWest : B1.P : area
BrownSpots" // PANDA
// ... and so on
};
void Bear::print(
ostream& os )
{ ZooAnimal::print( os ); // static invocation
os
<< "tZoo Area Location:nt";
os << locTable[ zooArea ] <<
"n";
}
,
:
1.
. , ,
isA() za ZooAnimal .
isA() pz ZooAnimal
.
#include "ZooAnimal.h"
main()
{
ZooAnimal
za;
ZooANimal *pz;
// ...
za.isA( cout ); // nonvirtual
invocation
(*pz).isA( cout ); // virtual invocation}
2.
. ,
#include
<stream.h>
#include "Bear.h"
#include "ZooAnimal.h"
main()
{
Bear yogi ( "cartoon Bear", BEAR,"ursus cartoons" );
ZooAnimal circus(
"circusZooAnimal" );
ZooAnimal *pz;
pz = &circus;cout <<
"virtual : ZooAnimal::print()n";
pz->print( cout );
pz =
&yogi;cout << "nvirtual : Bear::print()n";
pz->print( cout
);
cout << "nnonvirtual : ZooAnimal::print()n";
cout <<
"note : isA() is invoked virtuallyn";
pz->ZooAnimal::print( cout
);}
:
virtual :
ZooAnimal::print()
ZooAnimal name : circus
ZooAnimal virtual :
Bear::print()
ZooAnimal name : cartoon Bear
scientific name : ursus
cartoonus
Zoo Area Location:NorthWest : B1 : area Brown
nonvirtual :
ZooAnimal::print()
note: isA() is invoked virtually
ZooAnimal name:
cartoon Bear
scientific name: ursus cartoonus
3.
.
,
,
.
Panda : indName,
cell, , .
Panda:
#include <stream.h>
class Panda :
public Bear
{
public:
Panda( char *nm, int room, char *s = "Panda",char *sci
=
"Ailuropoda Melaoleuca", ZooLocs loc = PANDA );
~Panda() { delete
indName; }
void print( ostream& );
void isA( ostream&
);
protected:
char *indName; // name of individual animal
int
cell;
};
#include <string.h>
Panda::Panda( char *nm, int
room, char *s,char *sci, ZooLocs
loc ): Bear( s, loc, sci ), cell( room
)
{ indName = new char [strlen(nm) + 1];
strcpy( indName, nm
);}
isA() print(), Panda ,
. :
void
Panda::isA( ostream& os )
{
Bear::isA( os );
os << "twe call
our friend:t";
os << indName << "n";
}
void Panda::print(
os )
{
Bear::print( os );
os << "tRoom Location:t";
os
<< cell << "n";
}
. print()
ZooAnimal.
(<<).
za.print( os
);
,
za.
#include
<iostream.h>
#include "ZooANimal.h"
#include "Bear.h"
#include
"Panda.h"
ZooANimal circus( "circusZooAnimal");
Bear yogi("cartoon
Bear",BEAR,"ursus cartoonsus");
Panda yinYang("Yin Yang",1001,"Giant
Panda");
main() {
cout << "Invokation by a ZooAnimal
object:n"
<< circus << "n";
cout << "nInvokation by a
Bear object:n"
<< yogi << "n";
cout << "nInvokation
by a Panda object:n"
<< yinYang << "n";
};