« Konwersja w górę i rzutowanie w dół, lekcja »
12. Konwersja w górę i rzutowanie w dół hierarchii dziedziczenia. (lekcja)
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!
Autor: pekfos
Programowanie obiektowe, C++

Konwersja w górę i rzutowanie w dół

[lekcja] 12. Konwersja w górę i rzutowanie w dół hierarchii dziedziczenia.

Wprowadzenie

Dziedziczenie publiczne modeluje relację "jest". Obiekt klasy pochodnej jest także obiektem klasy bazowej. To znaczy, że obiekt klasy pochodnej może być traktowany tak samo jak obiekt klasy bazowej, ponieważ klasa pochodna dziedziczy to, co było publiczne w klasie bazowej, czyli interfejs.

Skoro obiekty jednej klasy obiektami innej klasy (ale nie zawsze odwrotnie), to występują konwersje między tymi klasami. W graficznych sposobach przedstawiania hierarchii dziedziczenia (na przykład diagramy UML) przyjęło się, że klasy bazowe są na górze, a pochodne na dole. Stąd wzięły się terminy konwersji w górę i rzutowania w dół.
C/C++
/* Przykładowy diagram dziedziczenia UML

  +-----------+
  | Prostokat |          //bazowa na górze
  +-----------+
        ^
        |
   +---------+
   | Kwadrat |           //pochodna na dole
   +---------+
*/

class Prostokat
{
};

//Kwadrat to prostokąt, ale nie zawsze prostokąt to kwadrat
class Kwadrat
    : public Prostokat
{
};

Konwersja w górę

Konwersja w górę hierarchii dziedziczenia (z pochodnej na bazową).
C/C++
Kwadrat kw;

Prostokat p, * pp;
p = kw; // konwersja w górę obiektu
pp = & kw; // konwersja w górę adresu
Konwersja w górę jest automatyczna i bezpieczna, bo obiekt klasy pochodnej jest obiektem klasy bazowej (Każdy kwadrat jest prostokątem).
Należy zauważyć, że obiekt klasy pochodnej jest niemal zawsze większy od obiektu klasy bazowej. W przypadku konwersji w górę obiektu klasy pochodnej, zostanie on przycięty.

Rzutowanie w dół

Rzutowanie w dół hierarchii dziedziczenia nie jest automatyczne, ponieważ obiekt klasy bazowej nie zawsze jest obiektem klasy pochodnej (Nie każdy prostokąt jest kwadratem). Rzutowanie w dół w C++ dotyczy tylko wskaźników i służy do tego
dynamic_cast <>
.
Jeśli nie można wykonać rzutowania, dynamic_cast<> zwraca wskaźnik pusty.
C/C++
Kwadrat kw, * kp;
Prostokat * p;

p = & kw; //w górę na bazową

kp = dynamic_cast < Kwadrat *>( p );

if( kp )
{
    //ok
}
else
{
    //obiekt pod adresem p nie jest typu Kwadrat
}
Błąd kompilacji:
error: cannot dynamic_cast ‘p’ (of type ‘class Prostokat*’) to type ‘class Kwadrat*’ (source type is not polymorphic)
Rzutowanie w dół jest wykonywane w czasie działania programu (bo nie wiadomo, co może być pod wskazanym adresem). To wymaga zapisania informacji o typie w obiektach (o czym na następnej lekcji).
Poprzedni dokumentNastępny dokument
DziedziczenieMetody wirtualne