Wstęp do Programowania 2

Podobne dokumenty
Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Niejawne funkcje składowe

Konstruktor kopiujący

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Projektowanie klas c.d. Projektowanie klas przykład

PARADYGMATY PROGRAMOWANIA Wykład 3

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Wstęp do Programowania 2

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006)

Operatory na rzecz typu TString

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

Programowanie obiektowe w C++ Wykład 12

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Programowanie Obiektowo Zorientowane w języku C++ Klasy, pola, metody

Język C++ wykład VII. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VII. dr Jarosław Mederski. Spis.

Programowanie obiektowe i C++ dla matematyków

Programowanie Obiektowew języku C++ Zadania L4

PARADYGMATY PROGRAMOWANIA Wykład 2

Plik klasy. h deklaracje klas

Programowanie w C++ Wykład 13. Katarzyna Grzelak. 4 czerwca K.Grzelak (Wykład 13) Programowanie w C++ 1 / 26

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 20 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 32

Wykład 4: Klasy i Metody

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Programowanie Obiektowe i C++

Wyliczanie wyrażenia obiekty tymczasowe

Język C++ Różnice między C a C++

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 4. Karol Tarnowski A-1 p.

Zajęcia nr 4 Programowanie obiektowe konstruktory. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Jzyk C++ cz 3. Jarosław Gramacki Instytut Informatyki i Elektroniki ( $)*)+' *, - ( ' )*'.' '',*/ *, ','*0) 1 / ) %*+ 2'' 2" ( $%%) )'20 )*0) 1 / )

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Zaawansowane programowanie w języku C++ Klasy w C++

Konstruktor kopiujacy

Programowanie obiektowe i C++ dla matematyków

Informatyka 2. Wykład nr 3 ( ) Politechnika Białostocka. - Wydział Elektryczny. dr inŝ. Jarosław Forenc

KLASY cz4. Dorota Pylak. destruktory składowe statyczne przeciążanie operatorów. wskaźniki

wykład V uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C++ klasy i obiekty wykład V dr Jarosław Mederski Spis Język C++ - klasy

Podstawy Programowania Obiektowego

Programowanie Obiektowe i C++

Programowanie Obiektowo Zorientowane w języku c++ Konstruktory

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Programowanie obiektowe

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

dr inż. Jarosław Forenc

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

it = 0; memset((void *)ptr, 0, items*sizeof(double)); cout << "Konstruktor sparametryzowany " << title << " adres: " << ptr << "\n";

Owad():waga(1),jadowitosc(false) {cout<<"konstruktor domyslny owada\n";}

Operacje wejścia/wyjścia (odsłona druga) - pliki

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

Programowanie obiektowe w języku C++ Zarządzanie procesami. dr inż. Jarosław Forenc. Przeładowanie (przeciążanie) operatorów

Język C++ wykład VIII

Szablony klas, zastosowanie szablonów w programach

Informacja o programowaniu w c++ Dr Maciej Bobrowski

PROGRAMOWANIE OBIEKTOWE W C++ cz. 2. Dziedziczenie, operacje wej cia-wyj cia, przeładowanie operatorów.

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 4. Karol Tarnowski A-1 p.

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

string Rodzaj[4]= {"TV ", "wieza ", "DVD ", "kino "}; string Producent[4]={"Phillips", "Sony ", "Sanyo ", "Samsung "};

TEMAT : KLASY POLIMORFIZM

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

PARADYGMATY PROGRAMOWANIA Wykład 4

Dziedziczenie & W slajdach są materiały zapożyczone z

Języki i paradygmaty programowania Wykład 2. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/18

Programowanie Obiektowew języku C++ Zadania L4

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

dr inż. Jarosław Forenc

Wstęp do programowania obiektowego. Przekazywanie parametrów do funkcji w C++ Metody i funkcje operatorowe Strumienie: standardowe, plikowe, napisowe

Operacje wejścia/wyjścia odsłona pierwsza

Dzisiejszy wykład. Klasa string. wersja prosta wersja ze zliczaniem odwołań. Wyjątki Specyfikator volatile Semafory

Materiały do zajęć VII

Przeciążenie operatorów

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Wykład :37 PP2_W9

2.4 Dziedziczenie. 2.4 Dziedziczenie Przykłady programowania w C - kurs podstawowy

Laboratorium 2. Funkcje wirtualne

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Wstęp do Programowania 2

Programowanie 2. Język C++. Wykład 3.

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Wstęp do wiadomości teoretycznych (nie, nie jest to masło maślane ani wstęp, wstępów proszę cierpliwie czytać)

Rozdział 4 KLASY, OBIEKTY, METODY

#include "stdafx.h" #include <iostream> #include "windows.h" using namespace std;

Wykład 8: klasy cz. 4

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Programowanie obiektowe Wykład 1. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20

TEMAT : KLASY DZIEDZICZENIE

Programowanie obiektowe język C++

Transkrypt:

Wstęp do Programowania 2 dr Bożena Woźna-Szcześniak bwozna@gmail.com Akademia im. Jana Długosza Wykład 8

Przykład realizowany na wykładzie Klasy StringBad i String. Wstępne pliki załaczone jako źródła. Przykład z ksi ażki: Stephen Prata. Język C++. Szkoła programowania. Wydanie V.

StringBad - interfejs #include <iostream> #ifndef STRNGBAD_H_ #define STRNGBAD_H_ class StringBad { private: char * str; // wskaznik ciagu int len; // dlugosc ciagu static int num_strings; // liczba obiektow public: StringBad(const char * s); // konstruktor StringBad(); // konstruktor domyslny ~StringBad(); // destruktor // funkcja zaprzyjazniona friend std::ostream & operator<<(std::ostream & os, const StringBad & st); ; #endif

Uwagi do przykładu Składowa statyczna, np. static int num_strings;, ma specjalna własność: program tworzy tylko jedna jej kopię, niezależnie od tego ile obiektów danej klasy zostało powołanych do życie. Wniosek: składowa statyczna jest współdzielona przez wszytkie obiekty klasy.

Klasa StringBad - implementacja #include <cstring> #include "strngbad.h" using std::cout; // inicjalizacja statycznej skladowej klasy int StringBad::num_strings = 0; // metody klasy // konstruuje obiekt StringBad na bazie ciagu jezyka C StringBad::StringBad(const char * s) { len = std::strlen(s); // ustalenie rozmiaru str = new char[len + 1]; // przydzial odpowiedniej ilosci pamieci std::strcpy(str, s); // inicjalizacja wskaxnika num_strings++; // uaktualnienie licznika obiektów cout << num_strings << ": \"" << str << "\" - obiekt utworzony.\n"; // komunikat diagnostyczny

Uwagi do przykładu Składowej statycznej nie można inicjalizować wewnatrz deklaracji klasy, gdyż deklaracja ta zawiera jedynie opis sposobu alokacji pamięci, jednak samej alokacji nie wykonuje. Alokacja i inicjalizacja pamięci dokonuje się w momencie utworzenia obiektu danej klasy. Pola statyczne inicjalizowane sa niezależnie za pomoca instrukcji znajdujacej się poza deklaracja klasy - powodem jest fakt, że składowe statyczne nie sa przechowywane jako część obiektu.

Klasa StringBad - implementacja StringBad::StringBad() // konstruktor domyslny { len = 4; str = new char[4]; std::strcpy(str, "C++"); // ciag domyslny num_strings++; cout << num_strings << ": \"" << str << "\" - obiekt domyslny utworzony.\n"; // komunikat diagnostyczny StringBad::~StringBad() // niezbedny teraz destruktor { cout << "\"" << str << "\" - obiekt usuniety, ";// diagnostyka --num_strings; // koniecznosc cout << "sa jeszcze " << num_strings << ".\n"; // diagnostyka delete [] str; // koniecznosc std::ostream & operator<<(std::ostream & os, const StringBad & st) { os << st.str; return os;

Klasa StringBad - test dzialania operatorow new i delete #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() { using std::endl; StringBad headline1("niech zyje bal!"); StringBad headline2("ferie tuz tuz..."); StringBad sports("narciarstwo"); cout << "Z ostatniej chwili: " << headline1 << endl; cout << "Temat dnia: " << headline2 << endl; cout << "Wiadomosci sportowe: " << sports << endl; callme1(headline1); cout << "Z ostatniej chwili: " << headline1 << endl; callme2(headline2); cout << "Temat dnia: " << headline2 << endl; cout << "Inicjalizacja obiektu ciagu innym obiektem:\n"; StringBad sailor = sports; cout << "Z kraju: " << sailor << endl; cout << "Przypisanie obiektu do innego obiektu:\n"; StringBad knot; knot = headline1; cout << "Ze swiata: " << knot << endl; cout << "Koniec main()\n"; return 0;

Klasa StringBad - test dzialania operatorow new i delete #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() {... void callme1(stringbad & rsb) { cout << "Obiekt ciagu przekazany przez referencje:\n"; cout << " \"" << rsb << "\"\n"; void callme2(stringbad sb) { cout << "Obiekt ciagu przekazany przez wartosæ:\n"; cout << " \"" << sb << "\"\n";

Klasa StringBad - test dzialania operatorow new i delete bws@bws:~/wyklady/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! Obiekt ciagu przekazany przez wartosc: "Ferie tuz tuz..." "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 2. Temat dnia: Inicjalizacja obiektu ciagu innym obiektem: Z kraju: Narciarstwo Przypisanie obiektu do innego obiektu: 3: "C++" - obiekt domyslny utworzony. Ze swiata: Niech zyje bal! Koniec main() "Niech zyje bal!" - obiekt usuniety, sa jeszcze 2. "Narciarstwo" - obiekt usuniety, sa jeszcze 1. "" - obiekt usuniety, sa jeszcze 0. *** glibc detected ***./a.out: double free or corruption (fasttop): 0x0000000000ffe050 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x78a96)[0x7f33cc61ca96]./a.out[0x400e9f]... ======= Memory map: ======== 00602000-00603000 rw-p 00002000 08:07 1574202

Gdzie jest problem???? #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() { using std::endl; StringBad headline1("niech zyje bal!"); StringBad headline2("ferie tuz tuz..."); StringBad sports("narciarstwo"); cout << "Z ostatniej chwili: " << headline1 << endl; cout << "Temat dnia: " << headline2 << endl; cout << "Wiadomosci sportowe: " << sports << endl; //... return 0;

Wykonanie problemu brak ws@bws:~/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo "Narciarstwo" - obiekt usuniety, sa jeszcze 2. "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 1. "Niech zyje bal!" - obiekt usuniety, sa jeszcze 0. bws@bws:~/wstepdoprog2/wyklad8$

Gdzie jest problem???? #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() { using std::endl; StringBad headline1("niech zyje bal!"); StringBad headline2("ferie tuz tuz..."); StringBad sports("narciarstwo"); cout << "Z ostatniej chwili: " << headline1 << endl; cout << "Temat dnia: " << headline2 << endl; cout << "Wiadomosci sportowe: " << sports << endl; callme1(headline1); cout << "Z ostatniej chwili: " << headline1 << endl; //... return 0;

Wykonanie problemu brak ws@bws:~/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! "Narciarstwo" - obiekt usuniety, sa jeszcze 2. "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 1. "Niech zyje bal!" - obiekt usuniety, sa jeszcze 0. bws@bws:~/wstepdoprog2/wyklad8$

Gdzie jest problem???? #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() { using std::endl; StringBad headline1("niech zyje bal!"); StringBad headline2("ferie tuz tuz..."); StringBad sports("narciarstwo"); cout << "Z ostatniej chwili: " << headline1 << endl; cout << "Temat dnia: " << headline2 << endl; cout << "Wiadomosci sportowe: " << sports << endl; callme1(headline1); cout << "Z ostatniej chwili: " << headline1 << endl; callme2(headline2); cout << "Temat dnia: " << headline2 << endl //... return 0;

Wykonanie problemu nr 1 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! Obiekt ciagu przekazany przez wartosc: "Ferie tuz tuz..." "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 2. Temat dnia: "Narciarstwo" - obiekt usuniety, sa jeszcze 1. "" - obiekt usuniety, sa jeszcze 0. "Niech zyje bal!" - obiekt usuniety, sa jeszcze -1.

Problem nr 1 Z jakiegos powodu przekazanie obiektu headline2 w argumencie funkcji callme2(headline2); powoduje wywołanie destruktora. Przekazanie przez wartość powinno zabezpieczać przed modyfikacja orginału, ale w naszym przypadku tak nie jest! Skad powyższe problemy: z automatycznego definiowania niejwnych funkcji składowych, których zachowanie nie jest zgodne z założeniami jakie - według programisty - powinna spełniać klasa. Dokładniej: Konstruktor kopiujący i Operator przypisania. Domyślny konstruktor kopiujacy nie zadbał o pole statyczne i wykonał tzw. kopiowanie płytkie. Domyślny operator przypisania również wykonał kopiowanie płytkie.

Konstruktor kopiujacy Postać: NazwaKlasy (const NazwaKlasy &); Zadaniem konstruktora kopiujacego jest kopiowanie obiektu istniejacego do obiektu nowo tworzonego. Konstrukora kopiujacego używa się w czasie inicjalizacji, ale nie używa się podczas zwykłego przypisania. Przykłady użycia: Dane jest: StringBad A( Niech zyje bal! ); StringBad B(A); StringBad B=A; StringBad B=StringBad(A); StringBad *B= new StringBad(A);

Częściowe rozwiazanie problemu #include <iostream> #ifndef STRNGBAD_H_ #define STRNGBAD_H_ class StringBad { private: char * str; // wskaznik ciagu int len; // dlugosc ciagu static int num_strings; // liczba obiektow public: StringBad(const char * s); // konstruktor StringBad(); // konstruktor domyslny StringBad(const StringBad &); // konstruktor kopiujacy ~StringBad(); // destruktor // funkcja zaprzyjazniona friend std::ostream & operator<<(std::ostream & os, const StringBad & st); ; #endif

Częściowe rozwiazanie problemu... StringBad::StringBad(const StringBad & st) { num_strings++; // aktualizacja skladowej statycznej... len = st.len; // ta sama dlugosc ciagu str = new char [len + 1]; // przydzial pamieci std::strcpy(str, st.str); // skopiowanie ciagu

Wykonanie Częściowe rozwiazanie problemu bws@bws:~/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! Obiekt ciagu przekazany przez wartosc: "Ferie tuz tuz..." "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 3. Temat dnia: Ferie tuz tuz... "Narciarstwo" - obiekt usuniety, sa jeszcze 2. "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 1. "Niech zyje bal!" - obiekt usuniety, sa jeszcze 0. bws@bws:~/wstepdoprog2/wyklad8$

Konstruktor kopiujacy pozwala na rozwiazanie kolejnego problemu #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() { using std::endl; StringBad headline1("niech zyje bal!"); StringBad headline2("ferie tuz tuz..."); StringBad sports("narciarstwo"); cout << "Z ostatniej chwili: " << headline1 << endl; cout << "Temat dnia: " << headline2 << endl; cout << "Wiadomosci sportowe: " << sports << endl; callme1(headline1); cout << "Z ostatniej chwili: " << headline1 << endl; callme2(headline2); cout << "Temat dnia: " << headline2 << endl cout << "Inicjalizacja obiektu ciagu innym obiektem:\n"; StringBad sailor = sports; cout << "Z kraju: " << sailor << endl; //... return 0;

Wszystko OK! bws@bws:~/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! Obiekt ciagu przekazany przez wartosc: "Ferie tuz tuz..." "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 3. Temat dnia: Ferie tuz tuz... Inicjalizacja obiektu ciagu innym obiektem: Z kraju: Narciarstwo "Narciarstwo" - obiekt usuniety, sa jeszcze 3. "Narciarstwo" - obiekt usuniety, sa jeszcze 2. "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 1. "Niech zyje bal!" - obiekt usuniety, sa jeszcze 0. bws@bws:~/wstepdoprog2/wyklad8$

Konstruktor kopiujacy to jednak nie wszystko... #include <iostream> using std::cout; #include "strngbad.h" void callme1(stringbad &); // obiekt przekazywany przez referencje void callme2(stringbad); // obiekt przekazywany przez wartosc int main() { using std::endl; StringBad headline1("niech zyje bal!"); StringBad headline2("ferie tuz tuz..."); StringBad sports("narciarstwo"); cout << "Z ostatniej chwili: " << headline1 << endl; cout << "Temat dnia: " << headline2 << endl; cout << "Wiadomosci sportowe: " << sports << endl; callme1(headline1); cout << "Z ostatniej chwili: " << headline1 << endl; callme2(headline2); cout << "Temat dnia: " << headline2 << endl cout << "Inicjalizacja obiektu ciagu innym obiektem:\n"; StringBad sailor = sports; cout << "Z kraju: " << sailor << endl; cout << "Przypisanie obiektu do innego obiektu:\n"; StringBad knot; knot = headline1; cout << "Ze swiata: " << knot << endl; cout << "Koniec main()\n"; return 0;

Gdzie jest problem? bws@bws:~/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! Obiekt ciagu przekazany przez wartosc: "Ferie tuz tuz..." "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 3. Temat dnia: Ferie tuz tuz... Inicjalizacja obiektu ciagu innym obiektem: Z kraju: Narciarstwo Przypisanie obiektu do innego obiektu: 5: "C++" - obiekt domyslny utworzony. Ze swiata: Niech zyje bal! Koniec main() "Niech zyje bal!" - obiekt usuniety, sa jeszcze 4. "Narciarstwo" - obiekt usuniety, sa jeszcze 3. "Narciarstwo" - obiekt usuniety, sa jeszcze 2. "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 1. "" - obiekt usuniety, sa jeszcze 0.

Gdzie jest problem? Instrukcja: knot = headline1; Dlaczego: wywołanie domyślnego operatora przypisania i zwiazane z tym Kopiowanie płytkie. Efekt: - obiekt usuniety, sa jeszcze 0., czyli pusty łańcuch zwiazany z obiektem headline2.

Rozwiazanie Przedefiniować własny operator przypisania. Pamiętaj może on być tylko przedefionowywany jako funkcja składowa! Pamiętaj aby zwracać referencje do obiektu. W przciwnym wypadku nie będzie można wykonywać instrukcji typu: A=B=C; StringBad & StringBad::operator=(const StringBad & st) { if (this == &st) return *this; delete [] str; len = st.len; str = new char[len + 1]; std::strcpy(str, st.str); return *this;

Potwierdzenie poprawności: bws@bws:~/mysvn/wyklady/2011-2012/matematyka/wstepdoprog2/wyklad8$./a.out 1: "Niech zyje bal!" - obiekt utworzony. 2: "Ferie tuz tuz..." - obiekt utworzony. 3: "Narciarstwo" - obiekt utworzony. Z ostatniej chwili: Niech zyje bal! Temat dnia: Ferie tuz tuz... Wiadomosci sportowe: Narciarstwo Obiekt ciagu przekazany przez referencje: "Niech zyje bal!" Z ostatniej chwili: Niech zyje bal! Obiekt ciagu przekazany przez wartosc: "Ferie tuz tuz..." "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 3. Temat dnia: Ferie tuz tuz... Inicjalizacja obiektu ciagu innym obiektem: Z kraju: Narciarstwo Przypisanie obiektu do innego obiektu: 5: "C++" - obiekt domyslny utworzony. Ze swiata: Niech zyje bal! Koniec main() "Niech zyje bal!" - obiekt usuniety, sa jeszcze 4. "Narciarstwo" - obiekt usuniety, sa jeszcze 3. "Narciarstwo" - obiekt usuniety, sa jeszcze 2. "Ferie tuz tuz..." - obiekt usuniety, sa jeszcze 1. "Niech zyje bal!" - obiekt usuniety, sa jeszcze 0.

Udoskonalona klasa String - interfejs #include <iostream> using namespace std; #ifndef STRING1_H_ #define STRING1_H_ class String { private: char * str; // wskaznik ciagu int len; // dlugosc ciagu static int num_strings; // liczba obiektów klasy static const int CINLIM = 80; // limit dlugosci ciagu na wejsciu public: String(const char * s); // konstruktor String(); // konstruktor domyslny String(const String &); // konstruktor kopiujacy ~String(); // destruktor int length () const { return len; String & operator=(const String &); // metody przeciazajace operatory String & operator=(const char *); char & operator[](int i); const char & operator[](int i) const; // funkcje zaprzyjaznione przeciazajace operatory friend bool operator<(const String &st, const String &st2); friend bool operator>(const String &st1, const String &st2); friend bool operator==(const String &st, const String &st2); friend ostream & operator<<(ostream & os, const String & st); friend istream & operator>>(istream & is, String & st); static int HowMany(); // metoda statyczna ; #endif

Udoskonalona klasa String - definicja #include <cstring> #include "string1.h" using std::cin; using std::cout; // inicjalizacja statycznej skladowej klasy int String::num_strings = 0; // metoda statyczna int String::HowMany() { return num_strings; String::String(const char * s) { // konstruuje obiekt String z ciagu C len = std::strlen(s); // ustawienie dlugosci ciagu str = new char[len + 1]; // przydzial pamieci std::strcpy(str, s); // inicjalizacja wskaznika ciagu num_strings++; // aktualizacja licznika obiektow

Udoskonalona klasa String - definicja String::String() // konstruktor domyslny { len = 4; str = new char[1]; str[0] = \0 ; // domyslny ciag obiektow klasy num_strings++; String::String(const String & st) { num_strings++; // aktualizacja skladowej statycznej len = st.len; // ta sama dlugosc ciagu str = new char [len + 1]; // przydzial pamieci std::strcpy(str, st.str); // skopiowanie ciagu String::~String() // destruktor (niezbedny) { --num_strings; // koniecznie delete [] str; // koniecznie

Udoskonalona klasa String - definicja // przypisywanie obiektu klasy String //do innego obiektu tej klasy String & String::operator=(const String & st) { if (this == &st) return *this; delete [] str; len = st.len; str = new char[len + 1]; std::strcpy(str, st.str); return *this; // przypisywanie ciagu C do obiektu klasy String String & String::operator=(const char * s) { delete [] str; len = std::strlen(s); str = new char[len + 1]; std::strcpy(str, s); return *this;

Udoskonalona klasa String - definicja // pelny dostep do znaków ciagu (dla obiektów zwyklych) char & String::operator[](int i){ return str[i]; // dostep (do odczytu) do znaków ciagu (dla obiektów const) const char & String::operator[](int i) const {return str[i]; // zaprzyjaznione funkcje przeciazajace operatory bool operator<(const String &st1, const String &st2) { return (std::strcmp(st1.str, st2.str) < 0); bool operator>(const String &st1, const String &st2) { return st2.str < st1.str; bool operator==(const String &st1, const String &st2) { return (std::strcmp(st1.str, st2.str) == 0);

Udoskonalona klasa String - definicja // wyprowadzenie ciagu na wyjscie ostream & operator<<(ostream & os, const String & st) { os << st.str; return os; // wczytywanie ciagu z wejscia (uproszczone) istream & operator>>(istream & is, String & st) { char temp[string::cinlim]; is.get(temp, String::CINLIM); if (is) st = temp; while (is && is.get()!= \n ) continue; return is;