При
компилация и изпълнение се получава следното:
Invokation by a ZooAnimal
object:
ZooAnimal name: circusZooAnimal
Invokation by a Bear object:
ZooAnimal
name: cartoon Bear
scientific name: ursus cartoonus Zoo
Area
Location:NorthWest:
B1: area BroWn
Invokation by a Panda object:
ZooAnimal
name: Giant Panda
scientific name: Ailuropoda
Melaoleucawe
call our friend: Yin YangZoo
Area Location:NorthWest:
B1.P:
area BrownSpotsRoom Location: 1001
Следващият пример показва
работа директно с указатели към обекти. Той вика виртуалната функция
isA().
#include <stream.h>
#include "ZooANimal.h"
#include
"Bear.h"
#include "Panda.h"
ZooAnimal circus( "circusZooAnimal"
);
Bear yogi("cartoon Bear", BEAR, "ursus cartoonus");
Panda yinYang("Yin
Yang", 1001, "Giant Panda");
main() {
ZooAnimal *pz;
pz =
&circus;
cout << "virtual: ZooAnimal::isA():n";
pz->isA(
cout );
pz = &yogi;cout << "nvirtual:
Bear::isA():n";
pz->isA( cout );pz = &yinYang;
cout <<
"nvirtual: Panda::isA():n";
pz->isA( cout );
}
При компилация
и изпълнение се получава следното:
virtual:
ZooAnimal::isA():
ZooAnimal name: circusZooAnimal
virtual:
Bear::isA():
ZooAnimal name: cartoon Bear
scientific name: ursus
cartoonus
virtual: Panda::isA():
ZooAnimal name: Giant Panda
scientific
name: Ailuropoda Melaoleuca
we call our friend: Yin Yang
В следващия
пример действителният тип на класа, адресиран чрез pz се разпознава по време на
компилация. Нека оставим виртуалния механизъм и да извикаме всяка функция
статично:
#include <stream.h>
#include "ZooAnimal.h"
#include
"Bear.h"
#include "Panda.h"
ZooAnimal circus(
"circusZooAnimal");
Bear yogi("cartoon Bear", BEAR, "ursus
cartoonus");
Panda yinYang("Yin Yang", 1001, "Giant Panda");
main()
{
ZooAnimal *pz = &yinYang;
cout << "Nonvirtual invokation of
Panda::isA():n";
((Panda*)pz) ->Panda::isA( cout );
pz =
&yogi;
cout << "nNonvirtual invokation of
Bear::isA():n";
((Bear*)pz) ->Bear::isA( cout );
}
Не
виртуалното извикване на Panda::isA() чрез указател към ZooAnimal изисква явно
обръщение. ZooAnimal няма представа за следващите извличания от класа Panda;
това е част от виртуалния механизъм, а не част от самия базов клас. При
компилация и изпълнение се получава следното:
Nonvirtual invocation of
Panda::isA():
ZooAnimal name: Giant Panda
scientific name: Ailoropoda
Melaoleucawe
call our friend: Yin Yang
Nonvirtual invocation of
Bear::isA():
ZooAnimal name: cartoon Bear
scientific name: ursuss
cartoonus
Този последен пример отпечатва смесен списък от указатели към
ZooAnimal. Той е реализиран с използването на следната не член функция print() -
print() трябва да има достъп до членовете данни на ZooAnimal, които не са
public, затова трябва да бъде обявена като friend за ZooAnimal.
#include
<iostream.h>
#include "ZooAnimal.h"
void print( ZooAnimal *pz,
ostream &os = cout ) {
while( pz )
{
pz->print( os );
os
<< "n";
pz = pz->next;
}
За нашия програмен пример имаме
нужда от указател към ZooAnimal, който да служи като глава на свързания
списък:
ZooAnimal *headPptr = 0;
main() дефинираме по следния
начин:
#include <stream.h>
#include "ZooAnimal.h"
extern
ZooAnimal makeList( ZooAnimal );
ZooAnimal *headPtr = 0;
main()
{
cout << "A Program to Illustrate Virtual Functionsn";
headPtr =
makeList( headPtr );
print( headPtr );
}
makeList(), на свой ред, е
дефинирана по следния начин:
#include <stream.h>
#include
"ZooAnimal.h"
#include "Bear.h"
#include "Panda.h"
ZooAnimal
circus( "circusZooAnimal" );
Bear yogi("cartoon Bear",BEAR,"ursus
cartoonus");
Panda yinYang("Yin Yang",1001,"Giant Panda");
Panda
rocky("Rocky",943,"Red Panda","Ailurus fulgens");
ZooAnimal *makeList(
ZooAnimal *ptr )
{// for simplicity, hand code list
ptr =
&yinYang;ptr->link( &circus );
ptr->link( &yogi
);
ptr->link( &rocky );
return ptr;
}