Metody wirtualne

34
Metody wirtualne Metody wirtualne

description

Metody wirtualne. Dlaczego metody wirtualne?. W C++ dla wskaźników i referencji dozwolona jest konwersja potomna → bazowa . przez taki wskaźnik lub referencję można odwoływać się jedynie do danych zadeklarowanych w klasie bazowej, oraz jedynie do metod klasy bazowej - PowerPoint PPT Presentation

Transcript of Metody wirtualne

Page 1: Metody wirtualne

Metody wirtualneMetody wirtualne

Page 2: Metody wirtualne

Dlaczego metody wirtualne?Dlaczego metody wirtualne?

W C++ W C++ dla wskaźników i referencji dozwolona dla wskaźników i referencji dozwolona jest konwersja potomna jest konwersja potomna → → bazowabazowa.. przez taki wskaźnik lub referencję można przez taki wskaźnik lub referencję można

odwoływać się jedynie do danych zadeklarowanych odwoływać się jedynie do danych zadeklarowanych w klasie bazowej, oraz jedynie do metod klasy w klasie bazowej, oraz jedynie do metod klasy bazowej bazowej

na podstawie klasy wskaźnika/referencji kompilator na podstawie klasy wskaźnika/referencji kompilator zdecyduje o wywołaniu metody kl. bazowej nazwet zdecyduje o wywołaniu metody kl. bazowej nazwet jeżeli obiekt jest klasy potomnej. jeżeli obiekt jest klasy potomnej.

Page 3: Metody wirtualne

class punktclass punkt{{ int x,y;int x,y;

public:public: void pokaz(); //rysuje punktvoid pokaz(); //rysuje punkt void ukryj();void ukryj();};};

class okrag: public punktclass okrag: public punkt{{ int r;int r;

public:public: void pokaz(); //rysuje punktvoid pokaz(); //rysuje punkt void ukryj();void ukryj();};};

okrag o;okrag o;punkt punkt **rp=rp=&&o;o;rprp->->pokaz(); pokaz(); //punkt::pokaz//punkt::pokaz

Page 4: Metody wirtualne

Dlaczego metody wirtualne?Dlaczego metody wirtualne?

okrag o;okrag o;punkt punkt **rp=rp=&&o;o;rprp->->pokaz(); pokaz(); // niech wywoła się okrag::pokaz// niech wywoła się okrag::pokaz

jak to zrealizować?jak to zrealizować?

Page 5: Metody wirtualne

class punktclass punkt{{ int x,y;int x,y;protectedprotected:: char klasa;char klasa;public:public: void pokaz(); //rysuje punktvoid pokaz(); //rysuje punkt

punkt(int x, int y)punkt(int x, int y) :x(x), y(y),:x(x), y(y), {{ klasa=‘p’klasa=‘p’;; }}};};

Rozwiązanie niedoskonałeRozwiązanie niedoskonałe WadliweWadliwe

class okrag: public punktclass okrag: public punkt{{ int r;int r;public:public: void pokaz(); //rysuje punktvoid pokaz(); //rysuje punkt okrag(int x, int y, int r)okrag(int x, int y, int r) :punkt(x,y), r(r):punkt(x,y), r(r) {{ klasa=‘o’klasa=‘o’;; }}};};

okrag o;okrag o;punkt punkt **rp=rp=&&o;o;if (if (rprp->klasa==‘p’)->klasa==‘p’) rp->punkt::rp->punkt::pokaz(); pokaz(); elseelse rp->okrag::rp->okrag::pokaz(); pokaz();

Page 6: Metody wirtualne

Metody wirtualneMetody wirtualne

Jeżeli Jeżeli zadeklarzadeklarujemyujemy metodę jako wirtualną metodę jako wirtualną toto kompilator uzupełni obiekty o pole determinujące kompilator uzupełni obiekty o pole determinujące klasę obiektu i przy wywoływaniu wybranych przez klasę obiektu i przy wywoływaniu wybranych przez nas metod wywoła metodę z właściwej klasy.nas metod wywoła metodę z właściwej klasy.

void void virtualvirtual punkt::punkt::ukryj();ukryj();

Metodę (albo operator) wystarczy raz zadeklarować Metodę (albo operator) wystarczy raz zadeklarować jako wirtualny, w klasach pochodnych możemy, ale jako wirtualny, w klasach pochodnych możemy, ale nie musimy używać słowa klnie musimy używać słowa kluczowegouczowego virtual. virtual.

Page 7: Metody wirtualne

class punktclass punkt

{{

int x,y;int x,y;

public:public:

void void virtualvirtual pokaz(); pokaz();

void void virtualvirtual ukryj(); ukryj();

};};

cclass okrag: public punktlass okrag: public punkt

{{

int r;int r;

public:public:

void pokaz(); void pokaz(); // virtual// virtual

void ukryj();void ukryj(); // virtual// virtual

};};

Metody wirtualneMetody wirtualne

Page 8: Metody wirtualne

Metody wirtualne - działanieMetody wirtualne - działanie DoDo pierwszej klasy w której w hierarchii klas pojawi się pierwszej klasy w której w hierarchii klas pojawi się

metoda wirtualna dodane zostanie dodatkowe niejawne pole metoda wirtualna dodane zostanie dodatkowe niejawne pole — adres tablicy — adres tablicy metodmetod wirtualnych. wirtualnych. zwiększy się rozmiar obiektów tej klasy. zwiększy się rozmiar obiektów tej klasy.

DDla obiektula obiektu,, którego klasy nie można jednoznacznie określić którego klasy nie można jednoznacznie określić na etapie kompilacjina etapie kompilacji,, odwołania do metody, bądź metod odwołania do metody, bądź metod zadeklarowanych jako wirtualne będą się odbywały pośrednio zadeklarowanych jako wirtualne będą się odbywały pośrednio poprzez tablicę metod wirtualnych poprzez tablicę metod wirtualnych będzie to działało wolniejbędzie to działało wolniej niż odwołanie bezpośrednie niż odwołanie bezpośrednie, , metody metody wirtualne wirtualne nie będą rozwijane inlinenie będą rozwijane inline,, bbędzie to działało szybciejędzie to działało szybciej,, niż gdybyśmy taką sztuczkę robili ręcznie, niż gdybyśmy taką sztuczkę robili ręcznie, kompilator nie pomyli się kompilator nie pomyli się (człowiek (człowiek – – wiadomo)wiadomo)..

Page 9: Metody wirtualne

Metody wirtualne - działanieMetody wirtualne - działanie OOdwołania przez wskaźnik i referencje będą dwołania przez wskaźnik i referencje będą

pośredniepośrednie

OOdwołania dwołania przezprzez kwalifik kwalifikacjęację obiektem będą obiektem będą bezpośrednie bezpośrednie a więc szybsze, a więc szybsze, metody (nawet zadeklarowane z virtual) metody (nawet zadeklarowane z virtual)

momogągą być rozwi być rozwijanejane inline inline..

Uwaga: Uwaga: metody klasy mogą zostać odziedziczone i metody klasy mogą zostać odziedziczone i aktywowane na rzecz obiektu klasy pochodnej, a aktywowane na rzecz obiektu klasy pochodnej, a więc odwołania do wirtualnych metod danej klasy z więc odwołania do wirtualnych metod danej klasy z innych metod tej klasy będą też pośrednieinnych metod tej klasy będą też pośrednie!!

Page 10: Metody wirtualne

class punktclass punkt{{ int x,y;int x,y;

public:public: void virtual pokaz(); void virtual pokaz(); void virtual ukryj();void virtual ukryj(); void przesun(int dx, int dy)void przesun(int dx, int dy) {{ ukryj();ukryj(); // wirtualna w punkt// wirtualna w punkt x+=dx;x+=dx; y+=dy;y+=dy; pokaz(); pokaz(); // wirtualna w punkt// wirtualna w punkt }}};};

class okrag: public punktclass okrag: public punkt{{ int r;int r;

public:public: void pokaz(); void pokaz(); void ukryj();void ukryj();};};

okrag o;okrag o;punkt punkt **rp=rp=&&o;o;rrpp->->pokaz(); pokaz(); //okrag::pokaz//okrag::pokaz

rrpp->przesun->przesun(); (); //punkt::przesun wywoła //punkt::przesun wywoła //okrag::pokaz i okrag::ukyj !!!//okrag::pokaz i okrag::ukyj !!!

Page 11: Metody wirtualne

Klasa polimorficznaKlasa polimorficzna klasa polimorficznaklasa polimorficzna to taka w której występuje to taka w której występuje

przynajmniej jedna metoda wirtualnaprzynajmniej jedna metoda wirtualna

Przykład korzyści z polimorfizmu:Przykład korzyści z polimorfizmu: deklarujemydeklarujemy listę przechowującą wskaźniki do punktów listę przechowującą wskaźniki do punktów

(klasa polimorficzna) - (klasa polimorficzna) - na liście umieszczać punkty okręgi na liście umieszczać punkty okręgi i inne figury.i inne figury.

przez wskaźniki możemy pokazać wszystkie figury przez wskaźniki możemy pokazać wszystkie figury (wywołując metodę wirtualną pokaz() – pośrednio), (wywołując metodę wirtualną pokaz() – pośrednio), możemy też przesuwać figury – wyw. się niewirtualna możemy też przesuwać figury – wyw. się niewirtualna metoda przesuń, ona wywoła właściwe, bo wirtualne pokaz metoda przesuń, ona wywoła właściwe, bo wirtualne pokaz i ukryj.i ukryj.

Page 12: Metody wirtualne

WWczesne i późne wiązanieczesne i późne wiązanie

WWczesnczesnee wiązanie wiązanie:: gdygdy metoda nie jest wirtualna lub jest wirtualna ale metoda nie jest wirtualna lub jest wirtualna ale

można określić z której klasy ma pochodzić to można określić z której klasy ma pochodzić to nazwa metody jest kojarzona z jej kodem nazwa metody jest kojarzona z jej kodem (wywołanie metody albo nawet rozwinięcie inline) (wywołanie metody albo nawet rozwinięcie inline) już na etapie kompilacjijuż na etapie kompilacji//linkowanialinkowania..

PPóźne wiązanie óźne wiązanie decyzjdecyzjaa co do wyboru klasy z co do wyboru klasy z zakresu zakresu której której

metodę wykonaćmetodę wykonać,, zostaje podjęta podczaszostaje podjęta podczas biegubiegu programuprogramu..

Page 13: Metody wirtualne

WWczesne i późne wiązanieczesne i późne wiązanie

Metody nie-wirtualne – zawsze wczesne wiązanie.Metody nie-wirtualne – zawsze wczesne wiązanie.

Zadeklarowanie metody jako wirtualnej nie wyklucza Zadeklarowanie metody jako wirtualnej nie wyklucza jej wczesnego wiązania, nastąpi ono, gdy:jej wczesnego wiązania, nastąpi ono, gdy: jawnie (operatorem zakresu) podamy o którą klasę nam jawnie (operatorem zakresu) podamy o którą klasę nam

chodzi, chodzi, wywołamy metodę bezpośrednio na rzecz obiektu (nie wywołamy metodę bezpośrednio na rzecz obiektu (nie

przez wskaźnik lub referencję).przez wskaźnik lub referencję).

Page 14: Metody wirtualne

Metody wirtualneMetody wirtualne

zaletzaleta:a: ogromna łatwość rozbudowy programu, ogromna łatwość rozbudowy programu, PPisząc kod możemy wykorzystywać metody isząc kod możemy wykorzystywać metody

których jeszcze nie napisanoktórych jeszcze nie napisano ! ! NNie musimy ie musimy powielaćpowielać takiego samego kodu w takiego samego kodu w

metodach różnych klasmetodach różnych klas (vide przesun()) (vide przesun()). . Nie grozi namNie grozi nam „uzupełni „uzupełnienieenie” ” już gotowego już gotowego kodu kodu

o nowe błędyo nowe błędy..

Page 15: Metody wirtualne

Konstruktory i destruktoryKonstruktory i destruktory

Konstruktor nie może być wirtualny Konstruktor nie może być wirtualny (dlaczego?)(dlaczego?)

Destruktor może i czasami powinien być Destruktor może i czasami powinien być virtual (dlaczego?)virtual (dlaczego?) Uwaga: Uwaga: Gdy w jakiejś klasie zadeklarujemy Gdy w jakiejś klasie zadeklarujemy

destruktor jako destruktor jako wwirtualirtualnyny, to w kl, to w klasachasach pocpochhodnych odnych destruktory destruktory też będteż będąą wirtualn wirtualnee (mimo (mimo że że ich ich nazwnazwyy w klas w klasachach pochodn pochodnych będą inneych będą inne).).

Page 16: Metody wirtualne

Static i virtualStatic i virtual

Metoda statyczna nie może być wirtualna Metoda statyczna nie może być wirtualna (dlaczego?).(dlaczego?).

Page 17: Metody wirtualne

Dziedziczenie metod wirtualnychDziedziczenie metod wirtualnych meoda wirtualna może zostać odziedziczona przez klasę meoda wirtualna może zostać odziedziczona przez klasę

pochodną pochodną może zostać przedefiniowana, w jej ciele może zostać przedefiniowana, w jej ciele możemy wywołać możemy wywołać

metodę wirtualną klmetodę wirtualną klasyasy bazowej. bazowej.

np.np.::

void okrag::pokaz() void okrag::pokaz() {{ punkt::pokaz(); // narysuj środek okręgupunkt::pokaz(); // narysuj środek okręgu //narysuj okrąg //narysuj okrąg }}

Page 18: Metody wirtualne

Przeciążanie a wirtualność Przeciążanie a wirtualność

wirtualność dotyczy tylko tej wirtualność dotyczy tylko tej metody/operatora którmetody/operatora któraa został zostałaa w danej klasie w danej klasie lub przodku zadeklarowanlub przodku zadeklarowanaa jako virtual, jako virtual, inne inne metody metody (o innych parametrach) są zwykłymi (o innych parametrach) są zwykłymi

metodami/operatorami.metodami/operatorami.

np.np. metoda nie wirtualna metoda nie wirtualna: :

void punkt::pokaz(char * opis){...}; void punkt::pokaz(char * opis){...};

Page 19: Metody wirtualne

ZZaprzyjaźnianie a wirtualnośćaprzyjaźnianie a wirtualność

WWirtualność irtualność jest niezależna od jest niezależna od zaprzyjaźnianiazaprzyjaźniania. . Zaprzyjaźnianie nie jest przechodnie, Zaprzyjaźnianie nie jest przechodnie, Zaprzyjaźnianie dotyczy tylko tej metody Zaprzyjaźnianie dotyczy tylko tej metody

(klasa::metoda) która została zaprzyjaźniona,(klasa::metoda) która została zaprzyjaźniona, MMetoda etoda przedefiniowana przedefiniowana w klasie pochodnej, w klasie pochodnej,

wirtualna czy nie, nie będzie automatycznie wirtualna czy nie, nie będzie automatycznie zaprzyjaźniona.zaprzyjaźniona.

Page 20: Metody wirtualne

WidocznośćWidoczność metod wirtualnych metod wirtualnych

Widoczność jest rozstrzygana na etapie kompilacjiWidoczność jest rozstrzygana na etapie kompilacji zatemzatem decyduje typ wskaźnika decyduje typ wskaźnika/referencji/referencji..

np.np., przyjmijmy, że , przyjmijmy, że wszystkwszystkie składowe klasy ie składowe klasy okrąg okrąg sa sa prywatneprywatne::

okrag o;okrag o;punkt *rp=&o;punkt *rp=&o;rp->pokaz(); rp->pokaz(); // OK – dlaczego?// OK – dlaczego?

Page 21: Metody wirtualne

Klasa abstrakcyjnaKlasa abstrakcyjna

Klasa abstrakcyjna, to klasa, która nie zawiera Klasa abstrakcyjna, to klasa, która nie zawiera żadnych obiektów.żadnych obiektów.

Klasa Klasa abstrakcyjna służy do definiowania abstrakcyjna służy do definiowania interfejsu/interfejsu/cech wspólncech wspólnychych rodziny innych klasrodziny innych klas (jej potomków)(jej potomków) np. klasa np. klasa abstrakcyjna „abstrakcyjna „figurafigura” „liczba” ” „liczba”

Dziedziczenie klas abstrakcyjnychDziedziczenie klas abstrakcyjnych

Page 22: Metody wirtualne

MMetodetodaa czysto wirtualn czysto wirtualnaa

WW CC++ klas++ klasaa abstrakcyjn abstrakcyjnaa to taka, która to taka, która zawierazawiera przynajmniej jedną metodę przynajmniej jedną metodę czysto czysto wirtualną wirtualną – tj. taką która jest wirtualna, i nie – tj. taką która jest wirtualna, i nie ma zdefiniowanego ciała. ma zdefiniowanego ciała.

void virtual figura::rysuj()=0;void virtual figura::rysuj()=0;

Page 23: Metody wirtualne

RTTIRTTI Ponieważ wskaźnikowi na przodka można przypisać adres Ponieważ wskaźnikowi na przodka można przypisać adres

potomka to typ wskaźnika nie determinuje klasy do której potomka to typ wskaźnika nie determinuje klasy do której należy obiekt wskazywany. należy obiekt wskazywany.

Czasami w trakcie działania programu pojawia się potrzeba Czasami w trakcie działania programu pojawia się potrzeba sprawdzenia do jakiej klasy dany obiekt należy. Jeżeli sprawdzenia do jakiej klasy dany obiekt należy. Jeżeli wskaźnik bądź referencja dotyczy klasy polimorficznej to wskaźnik bądź referencja dotyczy klasy polimorficznej to obiekt zawiera pole umożliwiające identyfikację klasy obiekt zawiera pole umożliwiające identyfikację klasy ((wskaźnik do tablicy metod wirtualnychwskaźnik do tablicy metod wirtualnych), na jego podstawie ), na jego podstawie mechanizm RTTI pozwala sprawdzać typy w trakcie biegu mechanizm RTTI pozwala sprawdzać typy w trakcie biegu programu. programu.

JJeżeli wskaźnik, bądź referencja dotyczy typu podstawowego eżeli wskaźnik, bądź referencja dotyczy typu podstawowego bądź klasy nie-polimorficznej to typ określany jest na bądź klasy nie-polimorficznej to typ określany jest na podstawie typu wskaźnika/referencji a nie rzeczywistego podstawie typu wskaźnika/referencji a nie rzeczywistego obiektu/zmiennej — bo nie ma danych by to zrobić inaczej.obiektu/zmiennej — bo nie ma danych by to zrobić inaczej.

Page 24: Metody wirtualne

RTTIRTTI

RTTI — RTTI — RunTime Type InformationRunTime Type Information

operator typeidoperator typeid

type_infotype_info typeid(arg)typeid(arg)

arg: typ, klasa, zmienna bądź obiektarg: typ, klasa, zmienna bądź obiekt

Page 25: Metody wirtualne

RTTIRTTI

class type_info class type_info {{ // tu prywatny konstr// tu prywatny konstruktoruktor kopiujący i op kopiujący i operatorerator przypisania przypisania // // nie można z zewnątrz tworzyć kopii obiektów tej klasynie można z zewnątrz tworzyć kopii obiektów tej klasypublic:public: virtual ~type_info();virtual ~type_info(); bool operator==(const type_info& rhs) const;bool operator==(const type_info& rhs) const; bool operator!=(const type_info& rhs) const;bool operator!=(const type_info& rhs) const; bool before(const type_info& rhs) const; bool before(const type_info& rhs) const; const char* name() const;const char* name() const;};};

Page 26: Metody wirtualne

RTTIRTTI

cclass A lass A { { virtual void a(){}; virtual void a(){}; };};class B:public A {};class B:public A {};class C:public B {};class C:public B {};

A a, *pa;A a, *pa;C c;C c;pa=&c;pa=&c;

typeid(C)==typeid(pa)typeid(C)==typeid(pa) //// 0 0 typeid(a)==typeid(*pa)typeid(a)==typeid(*pa) // // 00 typeid(c)==typeid(*pa) typeid(c)==typeid(*pa) //// 1 1 typeid(B).name() typeid(B).name() //// B B typeid(pa).name() typeid(pa).name() //// A * A * typeid(*pa).name() typeid(*pa).name() //// C C typeid(A).before(typeid(*pa)) typeid(A).before(typeid(*pa)) //// 1 1 typeid(B).before(typeid(*pa)) typeid(B).before(typeid(*pa)) //// 1 1 typeid(C).before(typeid(*pa)) typeid(C).before(typeid(*pa)) //// 0 0 typeid(C).before(typeid(a)) typeid(C).before(typeid(a)) //// 0 0

Page 27: Metody wirtualne

*_cast*_castoperatory rzutowania dla zastąpienia rzutowania operatory rzutowania dla zastąpienia rzutowania

w stylu języka Cw stylu języka C

staticstatic_cast_cast << type-id type-id > > (( wyrażeniewyrażenie )) dynamic_castdynamic_cast << type-id type-id > > (( wyrażeniewyrażenie )) reinterpretreinterpret_cast_cast << type-id type-id > > (( wyrażeniewyrażenie )) constconst_cast_cast << type-id type-id > > (( wyrażeniewyrażenie ))

to 4 operatory i 4 słowa kluczowe C++to 4 operatory i 4 słowa kluczowe C++ zaprojektowane by umożliwić większą kontrolę na poziomie kompilacji zaprojektowane by umożliwić większą kontrolę na poziomie kompilacji

i wykonania kodu nad (podatnymi na błędy) rzutowaniamii wykonania kodu nad (podatnymi na błędy) rzutowaniami pozwalają wyrazić intencję programistypozwalają wyrazić intencję programisty

Page 28: Metody wirtualne

staticstatic_cast_caststaticstatic_cast_cast << type-id type-id > > (( wyrażeniewyrażenie ))

rzutownie oparte na typach znanych podczas rzutownie oparte na typach znanych podczas kompilacjikompilacji

podobnie niebezpiczne jak rzutowanie C: podobnie niebezpiczne jak rzutowanie C: ((type-idtype-id ) ) wyrażeniewyrażenie

używać ostożnieużywać ostożnie działa szybkodziała szybko

nie dopuszcza się modyfikacji kwalifikacji nie dopuszcza się modyfikacji kwalifikacji const i volatile const i volatile wyrażeniawyrażenia

Page 29: Metody wirtualne

staticstatic_cast_caststaticstatic_cast_cast << type-id type-id > > (( wyrażenie wyrażenie ))

class A {};class A {};

class B:public Aclass B:public A{{

int method();int method();};};

int fun(A * pa)int fun(A * pa){{

static_cast<B*>(pa) -> method()static_cast<B*>(pa) -> method()// miejmy nadzieję, że pa wskazuje na B// miejmy nadzieję, że pa wskazuje na B

}}

Page 30: Metody wirtualne

dynamicdynamic_cast_castdynamicdynamic_cast_cast << type-id type-id > > (( wyrażenie wyrażenie ))

rzutowanie oparte o RTTI, używane ze rzutowanie oparte o RTTI, używane ze wskaźnikami i referencjamiwskaźnikami i referencjami

dla wskaźników zwraca NULL, jeśli dla wskaźników zwraca NULL, jeśli type-idtype-id nie jest nie jest ani typu ani typu wyrażeniawyrażenia ani jego rodzica ani jego rodzica

dla referencji w ww. przypadku zgłaszany jest dla referencji w ww. przypadku zgłaszany jest wyjątekwyjątek

bezpieczne, mniej szybkiebezpieczne, mniej szybkie nie dopuszcza się modyfikacji kwalifikacji nie dopuszcza się modyfikacji kwalifikacji

const i volatile const i volatile wyrażeniawyrażenia

Page 31: Metody wirtualne

dynamicdynamic_cast_castdynamicdynamic_cast_cast << type-id type-id > > (( wyrażenie wyrażenie ))

class A {};class A {};

class B:public Aclass B:public A{{};};

int fun()int fun(){{

A *pa, *aptr=new A;A *pa, *aptr=new A;B *pb, *bptr=new B;B *pb, *bptr=new B;......pa=dynamic_cast<A*>(bptr); pa=dynamic_cast<A*>(bptr); // OK// OKpb=dynamic_cast<B*>(aptr); pb=dynamic_cast<B*>(aptr); // NULL !!!// NULL !!!pb=dynamic_cast<B*>(pa); pb=dynamic_cast<B*>(pa); // OK// OK

}}

Page 32: Metody wirtualne

reinterpretreinterpret_cast_cast

reinterpret_reinterpret_castcast << type-id type-id > > (( wyrażenie wyrażenie ))

rzutownie oparte na typach znanych podczas kompilacjirzutownie oparte na typach znanych podczas kompilacji używane dla arytmetyki adresów (wskaźników), do konwersji typu „w używane dla arytmetyki adresów (wskaźników), do konwersji typu „w

górę”górę” używaj dla wskaźników i liczb całkowitych (wyraź swoją intencję)używaj dla wskaźników i liczb całkowitych (wyraź swoją intencję) niech Twój szef myśli że jesteś guru programowania w C++ ;)niech Twój szef myśli że jesteś guru programowania w C++ ;)

CLASS *ptr;CLASS *ptr;

......

unsigned int adress=reinterpret_cast<unsigned int>(ptr);unsigned int adress=reinterpret_cast<unsigned int>(ptr);

Page 33: Metody wirtualne

constconst_cast_castconstconst_cast_cast << type-id type-id > > (( wyrażenie wyrażenie ))

rzutownie oparte na typach znanych podczas kompilacjirzutownie oparte na typach znanych podczas kompilacji używaj dla wskaźników i referencjiużywaj dla wskaźników i referencji używaj dla usunięcia kwalifikacji cost i/lub volatile używaj dla usunięcia kwalifikacji cost i/lub volatile wyrażeniawyrażenia

class CLASSclass CLASS{{

int member;int member;

int CLASS::constmethod() constint CLASS::constmethod() const{{

const_cast<CLASS *>(this) -> member++;const_cast<CLASS *>(this) -> member++;// const_cast<int>(member)++; // const_cast<int>(member)++; ERRORERROR

}}}}

Page 34: Metody wirtualne

mutablemutable słowo kluczowe mutable sprawia, że nie-stała i słowo kluczowe mutable sprawia, że nie-stała i

nie-statyczna zmienna klasowa pozostanie nie-nie-statyczna zmienna klasowa pozostanie nie-stała w stałych metodach klasystała w stałych metodach klasy

class CLASSclass CLASS{{

mutable int member;mutable int member;

int CLASS::constmethod() constint CLASS::constmethod() const{{

member++; member++; // bo member jest mutable // bo member jest mutable }}

}}