Програмна среда С


Категория на документа: Информатика


извиква конструктора по подразбиране на ZooAnimal.
Достъп до членовете на виртуален базов клас
Всеки обект от класовете Raccoon и Bear поддържа свое собствено множество от членове на ZooAnimal, което може да бъде достигнато точно по същия начин както онаследените членове от невиртуални извличания. При едно отделно преглеждане на програмния код не може да се направи разлика между употребата на обект на извличане от виртуален и на невиртуален базов клас; единствената разлика е в начина на отделянето на частта от обеста, съответна на базовия клас.
При невиртуално извличане всеки извлечен обект от класа съдър-жа долепващи се базова и извлечена част на класа (виж Фигура 7.4 ). Обект от класа Bear, например, има базова част ZooAnimal и Bear част. При виртуално извличане всеки обект от извлечения клас съдържа извлечена част и указател към частта, съответна на виртуалния базов клас. Виртуалният базов клас не се съдържа в обекта от извлечения клас. Това е илюстрирано за класовете Bear, Raccoon и Pandaна Фигура 8.3.Един виртуален базов клас се подчинява на същите правила заpublic и private, както и при невиртуално извличане:
• Онаследените членове при public виртуално извличане запазватнивото си на достъп - public или protected - в извлечения клас.
• Онаследените членове при private виртуално извличане стават private членове на извлечения клас.
Какво става, когато еднократно-отдалечено извличане, такова катоPanda, включва едновременно public и private образци на един виртуален базов клас? Например,
class ZooAnimal
{public:
void locate();
protected:
short zooArea;

};
class Bear :
public virtual ZooAnimal { /* ... */ };
class Raccoon :
private virtual ZooAnimal { /* ... */ };
class Panda :
public Bear, public Raccoon { /* ... */ };
class Raccoon : public virtual ZooAnimal
class Bear : public virtual ZooAnimal
Фигура 8.3 Представяне на виртуален базов клас
Panda наследява само едно копие на zooArea и locate(), защото ZooAnimal е виртуален базов клас. Въпросът е дали на Panda е разрешен достъпа до тези членове? При public онаследяване Panda има достъп до тези два члена на ZooAnimal. Обаче, те не са достъпни за Panda при private онаследяване. Кой вид онаследяване се взема впредвид при виртуално извличане? Вярно ли е следното обръщение?
Panda p;p.locate();
Да, обръщението е вярно. Взема се впредвид public онаследяването. Panda има достъп до zooArea и locate(). Като цяло, независимо от брояна образците на виртуалните базови класове в йерархията на онаследяването, ако съществува отделен public образец, един споделен образец при извличане се разглежда като public.
ZooAnimal дефинира член функция locate(), която Raccoon наследява. Обръщението
Bear b;
b.locate(); // Bear instance
вика образеца на Bear, a не този на ZooAnimal. При невиртуално извличане обръщението
Panda p;
p.locate(); // which locate? e двузначно, ако Panda не дефинира свой собствен образец на locate(). Ако обаче ZooAnimal е виртуален базов клас едновременно за Raccoon и Bear,се вика образеца locate() на Bear. Двузначността е премахната. При виртуално извличане се взема същинският извлечен образец на член функцията. Затова се взема образеца locate() на Bear, а не този на ZooAnimal, наследен в Raccoon.
Ред на конструкторите и деструкторите
Виртуалните базови класове се конструират преди невиртуалните базови класове независимо от това къде се разположени в списъка с извличанията. Ако даден клас има два базови класа, и единият от двата е виртуален, винаги се вика пръв конструктора на виртуалния базов клас. Деструкторът на виртуалния базов клас се вика последен. Например,
class TeddyBear : public Bear,public virtual ToyAnimal { ... };
TeddyBear pooh;
Извикването на конструкторите за pooh става в следния ред:
ToyAnimal(); // virtual base
classZooAnimal(); // base class of Bear;
Bear(); // nonvirtual base
class TeddyBear();
Редът на извикване на деструкторите е обратен.
Ако един клас има повече виртуални базови класове, техните конструктори се викат по реда, по който са декларирани виртуалните базови класове. Като имаме в предвид това, можем да кажем, че се следва един нормален начин на извикване на конструкторите за един обектна извлечен клас.
По-сложен е случаят, в който виртуалният базов клас е nestedв йерархията на онаследяването. Например, Panda съдържа споделенияот Bear и Raccoon виртуален базов клас ZooAnimal. Откриването на присъствието на виртуален базов клас изисква претърсване на целия граф на онаследяването на извлечения клас. Например, действителната дефиниция на Panda не предполага, че съществува виртуален базов клас:
class Panda : public Endangered, public Herbivore,
public Raccoon, public Bear { ... };
Panda yin Yang;
Действителното виртуално извличане от ZooAnimal се появява много по-назад в графа на онаследяването, когато се дефинират Raccoon и Bear. За yinYang редът на обръщенията към конструкторите е следния:
ZooAnimal(); // virtual base class
Herbivore(); // base class declaration
orderEndangered();



Сподели линка с приятел:





Яндекс.Метрика
Програмна среда С 9 out of 10 based on 2 ratings. 2 user reviews.