Dziedziczenie umożliwia utworzenie nowego typu obiektu na podstawie już isniejącego.
Jeżeli w klasie pochodnej zostaną przedefiniowane funkcje, które nie są oznaczone jako wirtualne, wszystkie metody z klasy bazowej o identycznej nazwie przestają być widoczne.
class CBase
{
public:
int f() const { return 1; }
int f(int) const { return 1; }
void g() {}
};
class CDerived : public CBase
{
public:
// Przedefiniowanie
int f() const { return 2; }
};
//...
CDerived d;
//int x = d.f(1); // funkcja jest niewidoczna w klasie pochodnej
int y = d.f();
Klasa abstrakcyjna
Dostarcza uniwersalnego interfejsu dla klas pochodnych, tworząc szablon określający cechy wspólne klas pochodnych.
Niemożliwe jest utworzenie obiektu danego typu.
Klasa staje się abstrakcyjną, jeżeli chociaż jedną z metod zdefiniujemy jako czysto wirtualną (ang. pure virtual function):
class CAbstract
{
public:
CAbstract() {}
void f() = 0;
};
class CDerived1 : public CAbstract
{
public:
CDerived1() {}
};
class CDerived2 : public CAbstract
{
public:
CDerived2() {}
void f() {}
};
// ...
//CDerived1 d1; // Błąd kompilacji
CDerived2 d2;
d2.f();
Każda klasa pochodna, klasie abstrakcyjnej musi implementować funkcje czysto wirtualne, jeżeli będziemy chcieli utworzyć jej obiekt. W innym przypadku klasa pochodna, staje się klasą abstrakcyjną.
Metody, które są zadeklarowane jako czysto wirtualne, nie mają żadnego konkretnego adresu w tablicy VTABLE. Obiekt z niekompletną tablicą VTABLE nie może zostać utworzony, co jest sygnalizowane przez kompilator.
Tworzenie klas abstrakcyjnych gwarantuje, że nie zostaną one użyte w niepoprawny sposób, a także uniemożliwiają przekazywaniu takiego typu obiektu przez wartość.
Klasa, która zawiera wszystkie funkcje czysto wirtualne, określana jest jako klasa czysto abstrakcyjna (ang. pure abstract class).
Definicje funkcji czysto wirtualnych
Funkcje zadeklarowane jako czysto wirtualne mogą zawierać definicję. Umożliwia to dostarczenie wspólnej implementacji dla klas pochodnych.
Klasy z funkcjami czysto wirtualnymi, mimo dostarczenie definicji funkcji, pozostają abstrakcyjnymi.
Dziedziczenie prywatne
Atrybuty i składowe klasy bazowej są dostępne tylko dla klasy pochodnej, ponieważ nie jest dziedziczony interfejs, tylko implementacja. Żaden z elementów interfejsu klasy bazowej (nawet publiczny) nie jest dostępny dla użytkowników klasy pochodnej.
0 Komentarzy