Rzutowanie typów kompatybilnych za pomocą static_cast
Stronę tą wyświetlono już: 2398 razy
Funkcja szablonowa static_cast umożliwia rzutowanie kompatybilnych typów danych (np. int na double) jak również kompatybilnych typów wskaźnikowych. Przy czym ten drugi rodzaj rzutowania nie sprawdza poprawności typu w przypadku rzutowania w dół. Z tego powodu wszędzie tam, gdzie programista wie, że wskaźnik na klasę bazową jest dziedziczony przez z góry znany typ klasy można stosować rzutowanie za pomocą funkcji static_cast, w przeciwnym przypadku konieczne jest użycie funkcji dynamic_cast.
Oto prosty przykład:
- #include <iostream>
- class Base{
- public:
- virtual void fu() = 0;
- void baseFu() { std::cout << "baseFu is called" << std::endl; }
- };
- class ConcreteA : public Base{
- int k;
- public:
- ConcreteA() { k = 100; }
- virtual void fu() { std::cout << "fu from ConcreteA is called" << std::endl; }
- void concreteAfu() { std::cout << "concreteAfu is called " << k << std::endl; }
- };
- class ConcreteB : public Base{
- float k;
- public:
- ConcreteB() { k = 200; }
- virtual void fu() { std::cout << "fu from ConcreteB is called" << std::endl; }
- void concreteBfu() { std::cout << "concreteBfu is called " << k << std::endl; }
- };
- int main(){
- Base *base = new ConcreteA;
- ConcreteA* concreteA = static_cast<ConcreteA*>(base);
- concreteA->concreteAfu();
- base->fu();
- // to rzutowanie nie jest poprawne bo za base nie stoi wskaźnik na obiekt klasy ConcreteB
- ConcreteB* concreteB = static_cast<ConcreteB*>(base);
- concreteB->concreteBfu(); // z powodzeniem wywoła metodę concreteBfu ale zmienna k nie zostanie poprawnie wyświetlona
- std::cin.get();
- return 0;
- }
Wynik działania powyższego kodu będzie następujący:
concreteAfu is called 100 fu from ConcreteA is called concreteBfu is called 1.4013e-043
Wynika z tego niezbicie, że w przypadku gdy za wskaźnikiem na klasę bazową nie stoi obiekt klasy, na którą odbywa się rzutowanie, wtedy (chociaż samo rzutowanie się powiedzie) uzyskany wskaźnik na obiekt nie będzie zawierał wskaźnika na poprawnie zainicjalizowany obiekt klasy, na który rzutowanie się odbywa.
W przypadku rzutowania typu zmiennoprzecinkowego na całkowity część ułamkowa jest ucinana:
- double k1 = 10.234, k2 = -10.234;
- std::cout << "Rzutowanie dodatniej zmienoprzecinkowej na calkowita: " << static_cast<int>(k1) << std::endl;
- std::cout << "Rzutowanie ujemnej zmienoprzecinkowej na calkowita: " << static_cast<int>(k2) << std::endl;
Wynik powyższego kodu:
Rzutowanie dodatniej zmienoprzecinkowej na calkowita: 10 Rzutowanie ujemnej zmienoprzecinkowej na calkowita: -10

Tytuł:
Architektura oprogramowania bez tajemnic. Wykorzystaj język C++ do tworzenia wydajnych aplikacji i systemów
Autor:
Adrian Ostrowski, Piotr Gaczkowski

Tytuł:
Opus magnum C++ 11. Programowanie w języku C++. Wydanie II poprawione (komplet)
Autor:
Jerzy Grębosz

Tytuł:
Programowanie wieloplatformowe z C++ i wxWidgets 3
Autor:
Bartosz W. Warzocha

Tytuł:
Język C++ i przetwarzanie współbieżne w akcji. Wydanie II
Autor:
Anthony Williams

Tytuł:
C++ dla bystrzaków. Wydanie VII
Autor:
Stephen R. Davis

Tytuł:
Tablice informatyczne. Podstawy C++
Autor:
Radosław Sokół

Tytuł:
Opus magnum C++11. Programowanie w języku C++ (komplet)
Autor:
Jerzy Grębosz

Tytuł:
OpenCV 3. Komputerowe rozpoznawanie obrazu w C++ przy użyciu biblioteki OpenCV
Autor:
Adrian Kaehler, Gary Bradski

Tytuł:
C++ w 24 godziny. Wydanie VI
Autor:
Rogers Cadenhead, Jesse Liberty

Tytuł:
C++ Optymalizacja kodu. Sprawdzone techniki zwiększania wydajności
Autor:
Guntheroth Kurt