Dziedziczenie. Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie();

Slides:



Advertisements
Podobne prezentacje
C++ wykład 2 ( ) Klasy i obiekty.
Advertisements

C++ wykład 4 ( ) Przeciążanie operatorów.
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 2 Wojciech Pieprzyca.
Klasa listy jednokierunkowej Przekazywanie parametrów do funkcji
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 4 Wojciech Pieprzyca.
Programowanie obiektowe
1 Dzisiejszy wykład Klasa string wersja prosta wersja ze zliczaniem odwołań Wyjątki Specyfikator volatile.
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 3 Wojciech Pieprzyca.
Klasy i obiekty.
Metody wirtualne.
Wzorce.
Static, const, volatile.
Programowanie w środowisku sieciowym
Programowanie obiektowe w Javie
Szablony (wzorce) Przykład 1: Szablon klasy -
Licznik template<class Count_Type> class Count { public:
DZIEDZICZENIE · klasy bazowe i klasy pochodne WyświetlAutora( ) Autor
Struktury.
C++ wykład 5 ( ) Dziedziczenie.
C++ wykład 6 ( ) Polimorfizm.
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Wykład 8 Wojciech Pieprzyca
Podstawy programowania
Klasy w C++. Deklaracja klasy class NazwaTwojejKlasy { //w tym miejscu piszemy definicje typów, //zmienne i funkcje jakie mają należeć do klasy. }; //tutaj.
Programowanie obiektowe III rok EiT
Podstawy programowania II
T: Różnice pomiędzy programowaniem strukturalnym a obiektowym
Programowanie obiektowe w C++
Programowanie obiektowe III rok EiT
Java – coś na temat Klas Piotr Rosik
Dziedziczenie Maciek Mięczakowski
Programowanie obiektowe
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 7 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Programowanie obiektowe 2013/2014 Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Programowanie obiektowe 2013/2014
Prasek Aneta, Skiba Katarzyna. Funkcje stałe const to takie funkcje, które nie mogą modyfikować stanu obiektu. Oznacza to, że funkcja stała nie może zmieniać.
Kurs języka C++ – wykład 3 ( )
Programowanie w języku C++
Kurs języka C++ – wykład 5 ( )
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++ Przeładowanie operatorów Robert Nowak.
Kurs języka C++ – wykład 4 ( )
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
Klasy ( uzupełnienie ). Definicja klasy Klasa jest zbiorem logicznie powiązanych danych i funkcji, przeznaczonych do realizacji konkretnego zadania; Zamknięcie.
Konstruktory i Destruktory. Konstruktor Konstruktor — co to? Konstruktor — co to? jest metodą służącą do inicjowania obiektów danej klasy jest metodą.
Dziedziczenie wielobazowe. dana klasa może mieć kilka bezpośrednich klas bazowych: dana klasa może mieć kilka bezpośrednich klas bazowych: kolorpołożenie.
Dziedziczenie Wykład 7 Dziedziczenie sekwencyjne
Wykład 4 Klasa Vec, której konstruktory alokują pamięć dla obiektów 1.Przykład definicji klasy Vec 2.Definicje konstruktorów i destruktora 3.Definicja.
PO13-1 / 19 Wykład 13 Wyjątki i ich zgłaszanie Wyłapywanie wyjątków Obsługa wyjątków Wykorzystanie polimorfizmu Filtrowanie wyjątków Błędy w konstruktorach.
Wykład 8 Polimorfizm 1.Funkcje polimorficzne 2.Czyste funkcje wirtualne i klasy abstrakcyjne PO8-1 / 38.
Partnerstwo dla Przyszłości 1 Lekcja 28 Dziedziczenie i rodzaje dziedziczenia.
Podstawy informatyki Struktury Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Programowanie Obiektowe – Wykład 6
Kurs języka C++ – wykład 3 ( )
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Kurs języka C++ – wykład 4 ( )
Programowanie obiektowe
Zapis prezentacji:

Dziedziczenie

Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie(); void wypisz_nazwisko(); void wypisz_nazwisko(); void wypisz_wszystko(); void wypisz_wszystko();} class dorosly { char * imie, * nazwisko, * nazwisko, * nr_dowodu; * nr_dowodu;public: void wypisz_imie(); void wypisz_imie(); void wypisz_nazwisko(); void wypisz_nazwisko(); void wypisz_numer(); void wypisz_numer(); void wypisz_wszystko(); void wypisz_wszystko();}

Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie(); void wypisz_nazwisko(); void wypisz_nazwisko(); void wypisz_wszystko(); void wypisz_wszystko();} class dorosly: public osoba { char * nr_dowodu; char * nr_dowodu;public: void wypisz_numer(); void wypisz_numer(); void wypisz wszystko(); void wypisz wszystko();}

Dziedziczenie Wyraża związki hierarchiczne między klasami Wyraża związki hierarchiczne między klasami Rozbudowywanie istniejących klas, bez ich modyfikowania lub rekompilacji Rozbudowywanie istniejących klas, bez ich modyfikowania lub rekompilacji Wykorzystanie już gotowego kodu (definiujemy tylko to, co dodane lub zmienione) Wykorzystanie już gotowego kodu (definiujemy tylko to, co dodane lub zmienione)

Dziedziczenie Klasa bazowaosoba Klasa bazowaosoba Klasa pochodnadorosly Klasa pochodnadorosly każdy dorosły jest osobą dorosły jest przypadkiem szczególnym osoby

Klasa pochodna dorosły zawiera zmienne i metody: dorosły zawiera zmienne i metody: char * imie, * nazwisko odziedziczone, niedostępne dla kl. dorosly odziedziczone, niedostępne dla kl. dorosly char *nr_dowodu prywatne dla dorosly prywatne dla dorosly wypisz_imie(), wypisz_nazwisko() publiczne, odziedziczone z osoba publiczne, odziedziczone z osobaosoba::wypisz_wszystko() publiczne, odziedziczone i przysłonięte, publiczne, odziedziczone i przysłonięte, dostępne po kwalifikacji op. zakresu dostępne po kwalifikacji op. zakresu

Klasa pochodna zawiera wszystkie pola bazowej zawiera wszystkie pola bazowej dziedziczy wszystkie metody, może je przedefiniowywać dziedziczy wszystkie metody, może je przedefiniowywać do dostępnych lecz przysłoniętych nazw z zakresu klasy bazowej odwołujemy się za pomocą operatora zakresu do dostępnych lecz przysłoniętych nazw z zakresu klasy bazowej odwołujemy się za pomocą operatora zakresu

Klasa pochodna osoba.o; osoba.o; dorosly s; dorosly s; o.wypisz_imie(); o.wypisz_imie(); o.wypisz_nazwisko(); o.wypisz_nazwisko(); o.wypisz_wszystko(); o.wypisz_wszystko(); s.wypisz_imie(); // z osoba s.wypisz_imie(); // z osoba s.wypisz_nazwisko(); // z osoba s.wypisz_nazwisko(); // z osoba s.wypisz_numer(); // z dorosly s.wypisz_numer(); // z dorosly s.wypisz_wszystko(); // z dorosly s.wypisz_wszystko(); // z dorosly s.osoba::wypisz_wszystko(); // z osoba s.osoba::wypisz_wszystko(); // z osoba

Dostęp do pól kl. bazowej class pochodna : public bazowa; class pochodna : protected bazowa; class pochodna : private bazowa; class pochodna : bazowa; // : private

Dostęp do pól kl. bazowej sekcja w kl. bazowej privateprotectedpublic : private : privateniedostępneprivateprivate : protected : protectedniedostępneprotectedprotected : public : publicniedostępneprotectedpublic

Dostęp do pól kl. bazowej class a { public: public: int f(int); int f(int);}; class b:private a //można osłabić ograniczenie dostępu { public: public: a::f; // teraz a::f jest dziedziczone publicznie a::f; // teraz a::f jest dziedziczone publicznie};

Dostęp do pól kl. bazowej class baza {public: int ba_pub, int ba_pub, i; i;protected: int ba_prot; int ba_prot;private: int ba_priv; int ba_priv;}; class prot: protected baza {public: int i; int i; void metoda(); void metoda();protected: int prot_prot; int prot_prot; friend void friend_prot(); friend void friend_prot();};

Dostęp do pól kl. bazowej void prot::metoda() { int i; int i; i=baza::i; i=baza::i; i=i; i=i; i=prot::i; i=prot::i; i=ba_pub; i=ba_pub; i=baza::ba_pub; i=baza::ba_pub; i=prot::ba_pub; i=prot::ba_pub; i=ba_prot; i=ba_prot; i=baza::ba_prot; i=baza::ba_prot; i=prot::ba_prot; i=prot::ba_prot; // i=ba_priv; // i=baza::ba_priv; // i=prot::ba_priv; i=prot_prot; i=prot_prot; i=prot::prot_prot; i=prot::prot_prot;}

Dostęp do pól kl. bazowej void not_a_friend() { baza ba; baza ba; prot pr; prot pr; int i; int i; i=ba.i; i=ba.i; i=ba.ba_pub; i=ba.ba_pub; // i=ba.ba_prot; // i=ba.ba_priv; // i=pr.baza::i; !!!!! i=pr.i; i=pr.i; i=pr.prot::i; i=pr.prot::i; // i=pr.ba_pub; // i=pr.baza::ba_pub; // i=pr.prot::ba_pub; // i=pr.ba_prot; // i=pr.baza::ba_prot; // i=pr.prot::ba_prot; // i=pr.ba_priv; // i=pr.baza::ba_priv; // i=pr.prot::ba_priv; // i=pr.prot_prot; // i=pr.prot::prot_prot; }

Dostęp do pól kl. bazowej void friend_prot(void) { baza ba; baza ba; prot pr; prot pr; int i; int i; i=ba.i; i=ba.i; i=ba.ba_pub; i=ba.ba_pub; // i=ba.ba_prot; // i=ba.ba_priv; i=pr.baza::i; // !!!!! i=pr.baza::i; // !!!!! i=pr.i; i=pr.i; i=pr.prot::i; i=pr.prot::i; i=pr.ba_pub; i=pr.ba_pub; i=pr.baza::ba_pub; i=pr.baza::ba_pub; i=pr.prot::ba_pub; i=pr.prot::ba_pub; i=pr.ba_prot; i=pr.ba_prot; i=pr.baza::ba_prot; i=pr.baza::ba_prot; i=pr.prot::ba_prot; i=pr.prot::ba_prot; // i=pr.ba_priv; // i=pr.baza::ba_priv; // i=pr.prot::ba_priv; i=pr.prot_prot; i=pr.prot_prot; i=pr.prot::prot_prot; i=pr.prot::prot_prot;}

Konstruktor i destruktor dla klasy potomnej Konstruktorów się nie dziedziczy, ale Konstruktorów się nie dziedziczy, ale Kolejność konstrukcji obiektu klasy: Kolejność konstrukcji obiektu klasy: 1. wirtualne klasy bazowe 2. bezpośrednie klasy bazowe 3. obiektowe zmienne klasowe 4. dana klasa Destruktory - odwrotnie Destruktory - odwrotnie

Konstruktor i destruktor dla klasy potomnej – lista inicjalizacyjna Opisuje sposób inicjalizacji zmiennych klasowych zadeklarowanych w klasie (a nie odziedziczonych). Opisuje sposób inicjalizacji zmiennych klasowych zadeklarowanych w klasie (a nie odziedziczonych). Opisuje sposób wywołania konstruktorów przodków wirtualnych oraz bezpośrednich. Opisuje sposób wywołania konstruktorów przodków wirtualnych oraz bezpośrednich.

Przykład class osoba {protected: char * imie, char * imie, * nazwisko; * nazwisko; char * aloc_string(const char * s); char * aloc_string(const char * s);public: osoba(const char * im, const char * naz) osoba(const char * im, const char * naz) :imie(aloc_string(im)), :imie(aloc_string(im)), nazwisko(aloc_string(naz)) nazwisko(aloc_string(naz)) { }~osoba() { delete [] imie; delete [] imie; delete [] nazwisko; delete [] nazwisko; } void wypisz_imie(); void wypisz_imie(); void wypisz_nazwisko(); void wypisz_nazwisko(); void wypisz_wszystko(); void wypisz_wszystko();}

Przykład char * osoba::aloc_string(const char * s) { char * cp=new char[strlen(s) + 1]; char * cp=new char[strlen(s) + 1]; strcpy(cp, s); strcpy(cp, s); return cp; return cp;} void osoba::wypisz_imie() { cout << imie << " "; cout << imie << " ";} void osoba::wypisz_nazwisko() { cout << nazwisko << " "; cout << nazwisko << " ";} void osoba::wypisz_wszystko() { wypisz_imie(); wypisz_imie(); wypisz_nazwisko(); wypisz_nazwisko();}

Przykład - konstruktor klasy pochodnej class dorosly:public osoba {protected: char * nr_dowodu; char * nr_dowodu;public: dorosly(const char * imie, const char * nazwisko, const char * dowod) dorosly(const char * imie, const char * nazwisko, const char * dowod) :osoba(imie, nazwisko), nr_dowodu(aloc_string(dowod)) { }; };~dorosly() { delete [] nr_dowodu; delete [] nr_dowodu; }; }; void wypisz_numer(); void wypisz_numer(); void wypisz_wszystko(); void wypisz_wszystko();};

Przykład void dorosly::wypisz_numer() { cout << "dowod: " << nr_dowodu << " "; cout << "dowod: " << nr_dowodu << " ";} void dorosly::wypisz_wszystko() { osoba::wypisz_wszystko(); osoba::wypisz_wszystko(); wypisz_numer(); wypisz_numer();}

Przykład – wiele kl. pochodnych osoba doroslydziecko

class dziecko:public osoba {protected: osoba * mama, osoba * mama, * tata; * tata;public: dziecko(const char * imie, const char * nazwisko, osoba * mama, osoba * tata) dziecko(const char * imie, const char * nazwisko, osoba * mama, osoba * tata) :osoba(imie, nazwisko), mama(mama), tata(tata) :osoba(imie, nazwisko), mama(mama), tata(tata) { }; }; // ~dziecko() //wystarczy wygenerowany automatycznie – dlaczego? void wypisz_wszystko(); void wypisz_wszystko();};

Przykład void dziecko::wypisz_wszystko() { osoba::wypisz_wszystko(); osoba::wypisz_wszystko(); cout << "mama: " ; cout << "mama: " ; mama->wypisz_wszystko(); mama->wypisz_wszystko(); cout << "tata: " ; cout << "tata: " ; tata->wypisz_wszystko(); tata->wypisz_wszystko();}

Przykład – kl. bazowe i pochodne osoba doroslydziecko posel posel

class posel:public dorosly {protected: char * nr_immunitetu; char * nr_immunitetu;public: posel(const char * imie, const char * nazwisko, const char * dowod, const char * immunitet) posel(const char * imie, const char * nazwisko, const char * dowod, const char * immunitet) :dorosly(imie, nazwisko, dowod), nr_immunitetu(aloc_string(immunitet)) :dorosly(imie, nazwisko, dowod), nr_immunitetu(aloc_string(immunitet)) { // klasę osoba możemy skonstruować tylko pośrednio { // klasę osoba możemy skonstruować tylko pośrednio }; }; ~posel() ~posel() { delete [] nr_immunitetu; delete [] nr_immunitetu; } void wypisz_wszystko(); void wypisz_wszystko();};

void posel::wypisz_wszystko() { dorosly::wypisz_wszystko(); dorosly::wypisz_wszystko(); cout << "immunitet : " << nr_immunitetu; cout << "immunitet : " << nr_immunitetu;} Przykład

Struktury Struktury w C++ to też klasy Struktury w C++ to też klasy struct A { coś tam } struct A { coś tam } odpowiada odpowiada class A {public: coś tam } class A {public: coś tam }

Struktury i klasy Inicjatorem klamrowym można inicjalizować wyłącznie pola klasy w której wszystkie dane są publiczne i nie zdefiniowano konstruktora. Inicjatorem klamrowym można inicjalizować wyłącznie pola klasy w której wszystkie dane są publiczne i nie zdefiniowano konstruktora. struct s_xy { int x,y; int x,y;}; s_xy sxy={10,20}; // ok. //s_xy sxy1(10,10) - źle struct xy { int x,y; int x,y; xy(int x, int y) xy(int x, int y) : x(x), y(y) {} : x(x), y(y) {}}; //xy xy1={10,20}; źle xy xy1(10,10); //ok

Unie W C++ unia jest klasą, ale W C++ unia jest klasą, ale nie może zawierać obiektów z zdefiniowanymi konstruktorami bądź destruktorami nie może zawierać obiektów z zdefiniowanymi konstruktorami bądź destruktorami nie wolno ograniczać dostępu do pól - wszystkie pola muszą być publiczne nie wolno ograniczać dostępu do pól - wszystkie pola muszą być publiczne

Przykład – kl. bazowe i pochodne punkt punkt okrągodcinek prostokąt prostokąt Zadeklarować klasy, konstruktory, przesuń, += Zadeklarować klasy, konstruktory, przesuń, += W klasach zadeklarować zmienne: punkt: punkt: int kolor; xy polozenie int kolor; xy polozenie okrag :public punkt okrag :public punkt int promien int promien odcinek :public punkt odcinek :public punkt xy rozmiar; xy rozmiar; prostokąt :public odcinek prostokąt :public odcinek

Przykład – kl. bazowe i pochodne struct xy { int x,y; int x,y; xy(int x, int y): x(x), y(y) { }};

class punkt { int kolor; int kolor; xy polozenie; xy polozenie;public: punkt(int kolor, xy poz) :kolor(kolor), polozenie(poz) punkt(int kolor, xy poz) :kolor(kolor), polozenie(poz) { } void przesun(int dx, int dy) void przesun(int dx, int dy) { polozenie.x+=dx; polozenie.x+=dx; polozenie.y+=dy; polozenie.y+=dy; } punkt & operator+=(int d) punkt & operator+=(int d) { return *this; return *this; }};

class okrag:public punkt { int promien; int promien;public: okrag(int kolor, xy poz, int promien) okrag(int kolor, xy poz, int promien) :punkt(kolor, poz), promien(promien) :punkt(kolor, poz), promien(promien) { } okrag & operator+=(int d) okrag & operator+=(int d) { (promien*=100+d)/=100; (promien*=100+d)/=100; return *this; return *this; }};

class odcinek:public punkt { xy rozmiar; xy rozmiar;public: odcinek(int kolor, xy poz, int p2_x, int p2_y) odcinek(int kolor, xy poz, int p2_x, int p2_y) :punkt(kolor, poz), rozmiar(p2_x, p2_y) :punkt(kolor, poz), rozmiar(p2_x, p2_y) { } odcinek & operator+=(int d) odcinek & operator+=(int d) { (rozmiar.x*=100+d)/=100; (rozmiar.x*=100+d)/=100; (rozmiar.y*=100+d)/=100; (rozmiar.y*=100+d)/=100; return *this; return *this; }};

class prostokat:public odcinek {public: prostokat(int kolor, xy poz, int p2_x, int p2_y) prostokat(int kolor, xy poz, int p2_x, int p2_y) :odcinek(kolor, poz, p2_x, p2_y) :odcinek(kolor, poz, p2_x, p2_y) { } prostokat & operator+=(int d) prostokat & operator+=(int d) { odcinek::operator+=(d); odcinek::operator+=(d); return *this; return *this; }};

Przykład – kl. bazowe i pochodne xy xy punkt punkt okrągodcinek prostokąt prostokąt Jak się zmieni hierarchia klas? xy polozenie xy polozenie int x,y int x,y punkt :public xy punkt :public xy int kolor; int kolor; okrag :public punkt okrag :public punkt int promien int promien odcinek :public punkt odcinek :public punkt xy rozmiar; xy rozmiar; prostokąt :public odcinek prostokąt :public odcinek

class punkt :public xy { int kolor; int kolor; // xy polozenie // xy polozeniepublic: punkt(int kolor, xy poz) :kolor(kolor), xy(poz) punkt(int kolor, xy poz) :kolor(kolor), xy(poz) { } void przesun(int dx, int dy) void przesun(int dx, int dy) { x+=dx; // publiczne w przodku x+=dx; // publiczne w przodku y+=dy; y+=dy; } punkt & operator+=(int d) punkt & operator+=(int d) { return *this; return *this; }};

Konwersja potomna bazowa Automatyczna (niejawna) konwersja wskaźnika do klasy potomnej na wskaźnik do bazowej jest dozwolona przy dziedziczeniu publicznym Automatyczna (niejawna) konwersja wskaźnika do klasy potomnej na wskaźnik do bazowej jest dozwolona przy dziedziczeniu publicznym rationale rationale Przykład Przykład osoba o(…); dorosly d(…); dziecko x(Jaś, Kowalski, &o, &d); x.wypisz_wszystko() // nie wypisze dowodu d

Konwersja potomna bazowa Automatyczna (niejawna) konwersja wskaźnika do klasy potomnej na wskaźnik do bazowej jest dozwolona przy dziedziczeniu publicznym Automatyczna (niejawna) konwersja wskaźnika do klasy potomnej na wskaźnik do bazowej jest dozwolona przy dziedziczeniu publicznym uwaga: destrukcja przez wskaźnik po konwersji uwaga: destrukcja przez wskaźnik po konwersji osoba *o=new dorosly("aa", "bb", "cc"); delete o; // nie zwolni nr_dowodu rozwiązanie: destruktor wirtualny. rozwiązanie: destruktor wirtualny.

Konwersja potomna bazowa Skojarzenie referencji do klasy potomnej z obiektem klasy bazowej jest dozwolone przy dziedziczeniu publicznym Skojarzenie referencji do klasy potomnej z obiektem klasy bazowej jest dozwolone przy dziedziczeniu publicznym uwagi (konwersje wskaźników oraz referencji): uwagi (konwersje wskaźników oraz referencji): te konwersje są przechodnie te konwersje są przechodnie dozwolone wyłącznie dla dziedziczenia publicznego (aby uniemożliwić obejście ograniczenia dostępu do pól odziedziczonych jako private/protected) dozwolone wyłącznie dla dziedziczenia publicznego (aby uniemożliwić obejście ograniczenia dostępu do pól odziedziczonych jako private/protected)

Konwersja potomna bazowa class A {}; class B: public A {}; class C: private A {}; int fa(A a) {}; int fb(B b) {}; A a; A a; B b; B b; C c; C c; fa(a); fa(a); // konstruktor kopiujący A fa(b); // jak wyżej fa(b); // jak wyżej // fa(c); // błąd // fb(a); fb(b); fb(b); // fb(c); A *pa0=&a; A *pa0=&a; A *pa1=&b; A *pa1=&b; // A *pa2=&c; // B *pb=&a; // C *pc=&a; A &ra0=a; A &ra0=a; A &ra1=b; A &ra1=b; // A &ra2=c; // B &rb=a; // C &rc=a;

Konwersja potomna bazowa class A {}; class B: public A {}; class C: private A {}; class D: public B{}; int fa(A a) {}; D d; D d; fa(d); // przechodnie fa(d); // przechodnie

Konstruktor kopiujący klasy pochodnej to jest konstruktor, a zatem to jest konstruktor, a zatem obowiązuje koleność konstrukcji obiektów: zawsze wywołają się konstruktory klas bazowych. obowiązuje koleność konstrukcji obiektów: zawsze wywołają się konstruktory klas bazowych. można użyć listy inicjalizacyjnej by określić sposób wywołania konstruktora klasy bazowej można użyć listy inicjalizacyjnej by określić sposób wywołania konstruktora klasy bazowej Przypomnienie: konstruowane będą również obiekty zawarte w danym. Przypomnienie: konstruowane będą również obiekty zawarte w danym.

Konstruktor kopiujący klasy pochodnej class potomek:public baza {... }; potomek::potomek(const potomek & p) :baza(p) // niejawna konwersja do kl. bazowej {... };

Konstruktor kopiujący klasy pochodnej podobnie jak konstruktor domyślny i destruktor, konstruktor kopiujący może być generowany automatycznie podobnie jak konstruktor domyślny i destruktor, konstruktor kopiujący może być generowany automatycznie jeżeli w klasie potomnej nie zdefiniujemy go to zostanie wygenerowany jeżeli w klasie potomnej nie zdefiniujemy go to zostanie wygenerowany przed nim wywoła się konstruktor kopiujący klasy bazowej (a nie bezparametrowy, czyli odwrotnie niż w przypadku konstr. kop. nie-generowanego) przed nim wywoła się konstruktor kopiujący klasy bazowej (a nie bezparametrowy, czyli odwrotnie niż w przypadku konstr. kop. nie-generowanego) musi być dostępny k. kopiujący. klasy bazowej (być i być publiczny) musi być dostępny k. kopiujący. klasy bazowej (być i być publiczny)

Operator przypisania klasy pochodnej Wygenerowany automatycznie operator przypisania kopiuje składowe danej klasy pole po polu Wygenerowany automatycznie operator przypisania kopiuje składowe danej klasy pole po polu najpierw klasa bazowa kopiowana jest operatorem przypisania, potem obecna. najpierw klasa bazowa kopiowana jest operatorem przypisania, potem obecna. nie zostanie wygenerowany jeżeli klasa zawiera pola stałe albo referencje (w klasie albo przodkach), ani jeżeli w klasie bazowej lub obiekcie zawartym op.= był prywatny. nie zostanie wygenerowany jeżeli klasa zawiera pola stałe albo referencje (w klasie albo przodkach), ani jeżeli w klasie bazowej lub obiekcie zawartym op.= był prywatny. prawdopodobnie nie sprawdzi się dla pól wskaźnikowych prawdopodobnie nie sprawdzi się dla pól wskaźnikowych jeżeli napiszemy własny operator to odziedziczony operator nie wywoła się sam, trzeba to zrobić jawnie. jeżeli napiszemy własny operator to odziedziczony operator nie wywoła się sam, trzeba to zrobić jawnie.

Operator przypisania klasy pochodnej class potomek:public baza {... }; potomek & potomek::operator=(const potomek & p) { if (this == &p) if (this == &p) return *this; return *this; this->baza::operator=(p); this->baza::operator=(p); // alternatywy: baza *pb=this; (*pb)=p; // alternatywy: baza *pb=this; (*pb)=p; // baza *pb=this; pb->operator=(p); // baza *pb=this; pb->operator=(p); // baza &rb=*this; rb=p; // baza &rb=*this; rb=p; // przypisanie dla własnej klasy // przypisanie dla własnej klasy return *this; // zwrócenie wartości return *this; // zwrócenie wartości};

Przykład Konstruktory kopiujące i operatory przypisania dla klas osoba i dorosły Konstruktory kopiujące i operatory przypisania dla klas osoba i dorosły class osoba { char * imie, char * imie, * nazwisko; * nazwisko;…} class dorosly: public osoba { char * nr_dowodu; char * nr_dowodu;…}

Przykład osoba::osoba(const osoba &o) :imie(aloc_string(o.imie)),nazwisko(aloc_string(o.nazwisko)){} osoba & osoba::operator=(const osoba &o) { if (this == &o) if (this == &o) return *this; return *this; delete [] imie; delete [] imie; imie=aloc_string(o.imie); imie=aloc_string(o.imie); delete [] nazwisko; delete [] nazwisko; nazwisko=aloc_string(o.nazwisko); nazwisko=aloc_string(o.nazwisko); return *this; return *this;}

Przykład dorosly::dorosly(const dorosly & d) :osoba(d), nr_dowodu(aloc_string(d.nr_dowodu)) {} dorosly & dorosly::operator=(const dorosly & d) { if (this == &d) if (this == &d) return *this; return *this; this->osoba::operator=(d); this->osoba::operator=(d); delete [] nr_dowodu; delete [] nr_dowodu; nr_dowodu=aloc_string(d.nr_dowodu); nr_dowodu=aloc_string(d.nr_dowodu); return *this; return *this;}