Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do...

48
Wprowadzenie do programowanie Wprowadzenie do programowanie w języku C++ w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie zastąpi uważnego w nim uczestnictwa. Opracowanie to jest chronione prawem autorskim. Wykorzystywanie jakiegokolwiek fragmentu w celach innych niż nauka własna jest nielegalne. Dystrybuowanie tego opracowania lub jakiejkolwiek jego części oraz wykorzystywanie zarobkowe bez zgody autora jest zabronione. Roman Simiński [email protected] www.us.edu.pl/~siminski Autor Kontakt

Transcript of Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do...

Page 1: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Wprowadzenie do programowanie Wprowadzenie do programowanie w języku C++w języku C++

Obiekty i klasy

Część druga

Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie zastąpi uważnego w nim uczestnictwa.Opracowanie to jest chronione prawem autorskim. Wykorzystywanie jakiegokolwiek fragmentu w celach innych niż nauka własna jest nielegalne.

Dystrybuowanie tego opracowania lub jakiejkolwiek jego części oraz wykorzystywanie zarobkowe bez zgody autora jest zabronione.

Roman Simiński

[email protected]/~siminski

Autor

Kontakt

Page 2: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 2Strona :

Problem

Przewidywane jest napisanie obiektowej wersji programu, realizującego obliczenia z wykorzystaniem pól różnych, płaskich figur geometrycznych.

Należy zdefiniować klasy opisujące takie figury.

Kwadrat

KołoProstokąt

Trójkąt

Page 3: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 3Strona :

Analiza obiektowa

Stosując zasadę abstrakcji wyodrębniamy najistotniejsze cechy obiektów dla rozpatrywanego zagadnienia — obliczeń pól figur płaskich.

Kwadrat

Koło Prostokąt

Trójkąt

?

Page 4: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 4Strona :

Analiza obiektowa — klasa opisu kwadratu Square

Kwadrat

side

Square

?

side

Modelowany obiekt

Model analityczny

Model implementacyjny

Page 5: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 5Strona :

Hermetyzacja a pola publiczne i prywatne

Stosując zasadę hermetyzacji ukrywamy dane w części prywatnej i zapewniamy dostęp poprzez metody dostępowe (interfejsowe).

Pola publiczne a pola prywatne

s.side = 100; // Brak hermetyzacji, bezpo redni dost p do pólś ęcout << s.side; // Brak hermetyzacji, bezpo redni dost p do pólś ę

s.setSide( 100 ); // Hermetyzacja, dost p do pola za pomoc modyfikatoraę ącout << s.getSide(); // Hermetyzacja, dost p do pola za pomoc akcesoraę ą

Funkcje publiczne klasy można nieformalnie podzielić na;

akcesory — funkcje umożliwiające pobieranie wartości pól, akcesorem jest np. metoda getSide.

modyfikatory — funkcje dokonujące modyfikacji wartości pól, modyfikatorem jest np. metoda setSide.

realizatory — funkcje realizujące właściwe dla danej klasy usługi, realizatorem jest np. metoda area.

Page 6: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Stosowanie pól publicznych

Square

+setSide( double newSide )+getSide()+area()

-side: double

Copyright © Roman Simiński 6Strona :

Page 7: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 7Strona :

Obiekt klasy Square od strony programisty-użytkownika

Square s;

Deklaracja obiektu s klasy Square:

s.setSide( 100 );

Ustalenie boku o długości 100

double p;p = s.area();

Obliczenie pola kwadratu:

cout << "Pole kwadratu wynosi: " << s.area();

Obliczenie i wyprowadzenie pola kwadratu do stdout:

cout << "Bok kwadratu: " << s.getSide();

Pobranie aktualnej długości boku:

Page 8: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 8Strona :

Szkic programu obliczającego pole kwadratu

#include <iostream>using namespace std;

// ???

int main(){ double num; Square s;

cout << endl << "Obliczam pole kwadratu" << endl; cout << "Podaj bok: "; cin >> num; s.setSide( num );

cout << "Pole kwadratu wynosi: " << s.area();

return EXIT_SUCCESS;}

Page 9: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 9Strona :

Deklaracja klasy Square

class Square{ public :

// Składowe publiczne void setSide( double newSide ); double getSide(); double area();

private:

// Składowe prywatne double side;};

Page 10: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 10Strona :

Sekcje private i public

Dwie podstawowe sekcje:

private — elementy zadeklarowane w tej sekcji mogą być wykorzystywane

wyłącznie przez funkcje składowe danej klasy. Elementami tymi mogą być zarówno pola i funkcje. Mówi się o nich, że są prywatne.

public — elementy zadeklarowane w tej sekcji są dostępne również dla innych

elementów programu. Mówi się o nich, że są publiczne lub stanowią interfejs klasy.

Dwie metody kolejności zapisu sekcji public i private

class C{ public: // Cz ć publiczna klasyęś void interfaceMethod();

private: // Cz ć prywatna klasyęś void privateMethod();

int internalData;};

class C{ private: // Cz ć prywatna klasyęś void privateMethod();

int internalData;

public: // Cz ć publiczna klasyęś void interfaceMethod();};

Page 11: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 11Strona :

Definicja funkcji składowych

class Square{ public : void setSide( double newSide ); double getSide(); double area(); private: double side;};

void Square::setSide( double newSide ){ side = newSide;}

double Square::getSide(){ return side;}

double Square::area(){ return side * side;}

Funkcje składowe poza deklaracja klasy

W języku C++ występuje operator zakresu ::. Służy np. do deklarowania funkcji składowych poza ciałem klasy. Jego zastosowanie jest szersze, zapis Square:: oznacza, że występujący po nim element należy do klasy Square.

Page 12: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Obiekty i klasy w języku C++Obiekty i klasy w języku C++

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 12Strona :

Definicja funkcji składowych

class Square{ public :

void setSide( double newSide ) { side = newSide; }

double getSide() { return side; }

double area() { return side * side; }

private:

double side;}; Funkcje składowe w obrębie klasy

Page 13: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

KonstruktoryKonstruktory

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 13Strona :

Co się stanie gdy nie ustalimy rozmiaru boku obiektu klasy Square?

Square s;Square squares[ 3 ];

cout << s.area() << endl;

cout << squares[ 0 ].area() << endl;cout << squares[ 1 ].area() << endl;cout << squares[ 2 ].area() << endl;

????

Jak zainicjować obiekt na etapie jego definiowania?

Konstruktor jest specjalną funkcją, aktywowaną przez kompilator automatyczniew momencie gdy obiekt jest tworzony. Dzieje się tak zanim programista będzie mógł „dorwać” obiekt. Konstruktor ma przygotować obiekt do „życia”.

Konstruktor to specyficzna funkcja. Konstruktor nie ma typu rezultatu, nosi taką nazwę jak nazwa klasy i zwykle nie wywołuje się go jawnie w kodzie programu.

Page 14: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

KonstruktoryKonstruktory

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 14Strona :

Rodzaje konstruktorów

Występują cztery rodzaje konstruktorów:

Konstruktor domyślny (ang. default constructor) aktywowany, gdy tworzony jest obiekt bez jawnie określonych danych inicjalizujących.

Konstruktor ogólny (ang. general constructor), zwany też parametrowym, aktywowany gdy tworzymy obiekt z jawnie określonymi danymi inicjalizującymi.

Konstruktor kopiujący (ang. copy constructor) aktywowany wtedy, gdy tworzymy obiekt, inicjalizując go danymi z innego obiektu tej samej klasy.

Konstruktor rzutujący (ang. cast constructor) aktywowany wtedy, gdy tworzymy obiekt, inicjalizując go danymi z obiektu innej klasy.

Square s, squares[10];

Square s( 100 );

Square s( 100 );Square a = s, b( s );

Square s( 100 );Rectangle c = s, d( s );

Page 15: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor domyślny Konstruktor domyślny ―― default constructor default constructor

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 15Strona :

Wprowadzamy konstruktor domyślny klasy Square

class Square{ public :

Square(); // Konstruktor domy lny (bezparametrowy)ś

void setSide( double newSide ); double getSide(); double area();

private: double side;};

Okoliczności aktywowania konstruktora domyślnego

Square a; // Aktywacja: a.Square()Square b; // Aktywacja: b.Square()Square c; // Aktywacja: c.Square()

Square squares[ 3 ]; // Aktywacja: Square() dla ka dego elementu tablicy:ż// squares[ 0 ].Square()// squares[ 1 ].Square()// squares[ 2 ].Square()

Page 16: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor domyślny Konstruktor domyślny ―― default constructor default constructor

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 16Strona :

Dwie wersje realizacji konstruktora domyślnego:

Square::Square() : side( 0 ){}

Square::Square(){ side = 0;}

Wersja intuicyjna

Wersja z listą inicjalizacyjną

Square::Square() : side( 0 ){}

Nazwa pola

Lista inicjalizującakonstruktora

Wyrażenie inicjalizujące Lista inicjalizacyjna ma dwa zastosowania. Pierwsze z nich to inicjowanie pól obiektu.

Na liście może wystąpić nazwa pola, a w nawiasach wartość temu polu przypisywana.

Drugie zastosowanie listy inicjaliza-cyjnej zostanie omówione później.

Page 17: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor parametrowy, inaczej ogólny Konstruktor parametrowy, inaczej ogólny ―― general constructor general constructor

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 17Strona :

Czy można zainicjować obiekt na etapie deklaracji?

Square s( 100 );

cout << "Pole kwadratu wynosi: " << s.area();

Konstruktor ogólny pozwala na zainicjowanie pól obiektu na etapie jego deklaracji, wartościami określonymi przez programistę.

Square a( 1 ); // Aktywacja: a.Square( 1 )Square b( 5 ); // Aktywacja: b.Square( 5 )

Okoliczności aktywowania konstruktora ogólnego

Page 18: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor parametrowy, inaczej ogólny Konstruktor parametrowy, inaczej ogólny ―― general constructor general constructor

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 18Strona :

Wprowadzamy konstruktor parametrowy (ogólny) klasy Square

class Square{ public :

Square(); Square( double startSide );

void setSide( double newSide ); double getSide(); double area();

private: double side;};

Page 19: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor parametrowy, inaczej ogólny Konstruktor parametrowy, inaczej ogólny ―― general constructor general constructor

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 19Strona :

Dwie wersje realizacji konstruktora:

Square::Square( double startSide ){ side = startSide;}

Square::Square( double startSide ) : side( startSide ){}

Wersja intuicyjna

Wersja z listą inicjalizacyjną

Page 20: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor parametrowy, inaczej ogólny Konstruktor parametrowy, inaczej ogólny ―― general constructor general constructor

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 20Strona :

Jak zainicjować obiekt const?

const Square cs; // Niezainicjowany obiekt const

cs.setSide( 1.2 ); // Bł d – próba modyfikacji obiektu constą

cout << "Pole kwadratu wynosi: " << cs.area();

Słowo kluczowe const oznacza, że wartość zmiennej bądź argumentu nie może być zmieniana w czasie wykonania programu.

const Square cs( 1.2 ); // Zainicjowany obiekt const

cout << "Pole kwadratu wynosi: " << cs.area();

Konstruktor ogólny pozwala na zainicjowanie obiektów const

Page 21: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Operator zakresu w akcjiOperator zakresu w akcji

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 21Strona :

Wykorzystanie operatora zakresu ::

void Square::setSide( double newSide ){ side = newSide;}

Czy parametr funkcji setSide może nazywać się side? Czyli zamiast:

void Square::setSide( double side ){ side = side;}

definiujemy funkcję tak:

To nie będzie działać poprawnie

void Square::setSide( double side ){ Square::side = side;}

Ale można użyć operatora zakresu:

Parametr formalny funkcji przesłania w jej ciele pole ― gdy ich nazwy są jednakowe

Page 22: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Operator zakresu w akcjiOperator zakresu w akcji

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 22Strona :

Wykorzystanie operatora zakresu ::,cd. ...

Square::Square( double side ){ side = side;}

Podobny problem występuje w konstruktorze:

Square::Square( double side ){ Square::side = side;}

Operator zakresu odsłania przysłonięte pole

Square::Square( double side ) : side( side ){}

Problem przesłaniania pól nie występuje, gdy stosujemy listę inicjalizującą

Ten konstruktor nie będzie działał poprawnie

Ten konstruktor będzie działał poprawnie

Page 23: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Koncepcja przeciążania funkcjiKoncepcja przeciążania funkcji

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 23Strona :

Dlaczego dwa konstruktory posiadają tę samą nazwę?

Przeciążać można również nazwy zwykłych funkcji

int add( int a, int b ){ return a + b;}

double add( double a, double b ){ return a + b;}

cout << endl << "Dodawanie int :" << add( 1, 1 ) cout << endl << "Dodawanie double :" << add( 1.0, 1.0 );

W języku C++ istnieje możliwość przeciążania nazw funkcji

Identyfikator Square jest przeciążony i oznacza:

konstruktor domyślny Square(),

konstruktor ogólny Square( float side ).

Page 24: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Funkcje składowe constFunkcje składowe const

Obiekty i klasyJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 24Strona :

Uzupełniamy prototypy i definicje funkcji słowem kluczowym const

class Square{ public : Square(); Square( double startSide ); void setSide( double newSide ); double getSide() const; double area() const; private: double side;};

double Square::getSide() const{ return side;}

double Square::area() const{ return side * side;}

Metody ze specyfikacją const nie mogą modyfikować pól obiektu, mogą zatem być wywoływane dla obiektów stałych.

Page 25: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor kopiujący Konstruktor kopiujący ―― copy constructor copy constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 25Strona :

Dla typów wbudowanych można tak:

int j = 1;int i = j;

Czy można tak samo dla obiektów?

Square first( 100 );Square second = first;

Konstruktor kopiujący (ang. copy constructor), odpowiedzialny za skopiowanie zawartości jednego obiektu do drugiego — oba tej samej klasy — na etapie inicjalizacji.

Page 26: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor kopiujący Konstruktor kopiujący ―― copy constructor copy constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 26Strona :

Najlepiej zdefiniować konstruktor kopiujący

class Square{ public :

Square(); Square( double side ); Square( Square & otherSquare );

void setSide( double side ); double getSide() const; double area() const;

private: double side;};

Operator & oznacza referencję,umieszczony w deklaracji parametru oznacza przekazanie przez zmienną.

Page 27: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Square::Square( Square & otherSquare ){ side = otherSquare.side;}

Konstruktor kopiujący Konstruktor kopiujący ―― copy constructor copy constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 27Strona :

Dwie wersje realizacji konstruktora:

Wersja intuicyjna

Wersja z listą inicjalizacyjną

Square::Square( Square & otherSquare ) : side( otherSquare.side ){}

Page 28: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor kopiujący Konstruktor kopiujący ―― copy constructor copy constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 28Strona :

Okoliczności aktywowania konstruktora kopiującego

Square first( 100 ); // first.Square( 100 );Square second = first; // second.Square( first );Square third( first ); // third.Square( first );

cout << "Pole kwadratu pierwszego wynosi: " << first.area();cout << "Pole kwadratu drugiego wynosi : " << second.area();cout << "Pole kwadratu trzeciego wynosi : " << third.area();

W tej sytuacji konstruktor kopiujący nie działa!

Konstruktor kopiujący odpowiedzialny za skopiowanie zawartości obiektów tej samej klasy na etapie inicjalizacji.

Square first( 100 );Square second;

second = first; // Tutaj nie zostaje wywołany konstruktor kopiuj cyą

Page 29: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor kopiujący Konstruktor kopiujący ―― copy constructor copy constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 29Strona :

Nie można:

const Square first( 1 );Square second = first; // Bł d, niejawna referencja do obiektu constą

Rozwiązanie problemu z obiektem const:

Square::Square( const Square & otherSquare ) : side( otherSquare.side ){}

Page 30: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Będzie jeszcze jeden konstruktor...Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 30Strona :

Załóżmy, że istnieje klasa opisu prostokąta ― Rectangle

class Rectangle{ public :

// Konstruktory Rectangle(); Rectangle( double width, double height ); Rectangle( const Rectangle & otherRectangle );

// Modyfikatory void setWidth( double width ); void setHeight( double height );

// Akcesory double getWidth() const; double getHeight() const;

// Realizator double area() const;

private: double width, height;};

Page 31: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Będzie jeszcze jeden konstruktor...Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 31Strona :

Definicja konstruktorów i realizatora

// Konstruktor domy lnyśRectangle::Rectangle() : width( 0 ), height( 0 ){}

// Konstruktor ogólnyRectangle::Rectangle( double width, double height ) : width( width ), height( height ){}

// Konstruktor kopiuj cyąRectangle::Rectangle( const Rectangle & otherRectangle ): width( otherRectangle.width ), height( otherRectangle.height ){}

// Realizatordouble Rectangle::area() const{ return width * height;}

Page 32: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Będzie jeszcze jeden konstruktor...Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 32Strona :

Definicja modyfikatorów i realizatorów

// Modyfikatoryvoid Rectangle::setWidth( double width ){ Rectangle::width = width;}

void Rectangle::setHeight( double height ){ Rectangle::height = height;}

// Akcesorydouble Rectangle::getWidth() const{ return width;}

double Rectangle::getHeight() const{ return height;}

Page 33: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor rzutujący Konstruktor rzutujący ―― cast constructor cast constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 33Strona :

Mamy klasę Square i Rectangle, czy można tak:

Square s( 100 ); // Definicja zainicjowanego kwadratu sRectangle r( s ); // Definicja prostok ta r, zainicjowanego kwadratem są

Następuje tutaj inicjalizacja obiektu pewnej klasy obiektem innej klasy. Skąd kompilator ma wiedzieć, jak „przepisać” dane pomiędzy obiektami różnych klas?

Programista może określić metodę przepisania danych z obiektu jednej klasy do obiektu klasy innej, pisząc konstruktor rzutujący.

Page 34: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Konstruktor rzutujący Konstruktor rzutujący ―― cast constructor cast constructor

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 34Strona :

Konstruktor rzutujący odpowiedzialny za skopiowanie zawartości obiektów pewnej klasy do obiektu innej klasy na etapie inicjalizacji.

Potrzebny jest konstruktor rzutujący

Rectangle::Rectangle( const Square & square ): width( square.getSide() ), height( square.getSide() ){}

Zdefiniowany przez programistę sposób zainicjowania wysokości i szerokości prostokąta informacjami pochodzącymi z obiektu klasy opisującej kwadrat.

Page 35: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Informacja dodatkowa Informacja dodatkowa ―― parametry domyślne parametry domyślne

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 35Strona :

Parametry domyślne:

void fun( int i, float f = 0, char c = ’A’ );. . .fun( 10 ); // i == 10, f == 0, c == ’A’fun( 20, 3.15 ); // i == 20, f == 3.15, c == ’A’fun( 30, 22.1, ’Z’ ); // i == 30, f == 22.1, c == ’Z’

Parametr domyślny to wartość określona na etapie deklaracji funkcji, która zostanie automatycznie wstawiona do parametru formalnego, jeżeli dana funkcja zostanie wywołana bez odpowiedniego parametru aktualnego.

Parametry domyślne dotyczą funkcji składowych klas jak i funkcji niezwiązanychz klasami.

Parametry domyślne myszą być definiowane od końca listy parametrów.

Prototypy a parametry domyślne

void fun( int i, float f = 0, char c = ’A’ );. . .void fun( int i, float f, char c ){}

Jeżeli stosujemy prototypy funkcji, wartości parametrów domyślnych określa się właśnie w prototypie, w definicji funkcji już nie występują.

Page 36: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 36Strona :

Konstruktor domyślny ― default constructor

A();A( arg1 = wart1, arg2 = wart2, ... );

Konstruktor domyślny:

Jest bezparametrowy, lub posiada wszystkie parametry będące parametrami domyślnymi.

Jednoczesne wystąpienie obu powyższych form spowoduje błąd kompilacji.

Inicjuje obiekty, deklarowane lub (bądź tworzone) bez parametrów.

Dotyczy to również obiektów będących elementami tablicy.

A a, b, c; // Aktywacja: a.A(), b.A(), c.A()A tab[ 10 ]; // Aktywacja: A() dla ka dego z 10-ciu elementów tab:ż

// tab[ 0 ].A(), tab[ 1 ].A(), itd... .

Page 37: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 37Strona :

Konstruktor domyślny syntetyzowany przez kompilator

Jeżeli dla danej klasy nie zdefiniowano żadnego konstruktora, kompilator syntetyzuje konstruktor domyślny.

Jeżeli dla danej klasy zdefiniowano jakiś konstruktor inny od domyślnego, a ten jest potrzebny, lecz niezdefiniowany, kompilator zgłosi błąd.

Syntetyzowany konstruktor domyślny nie robi niczego mądrego. Nie należy się np. spodziewać po nim inicjalizacji pól wartościami zerowymi.

Programista powinien zdefiniować jawnie sposób inicjalizacji obiektów definiowanych bezparametrowo.

Służy do tego właśnie konstruktor domyślny, jego definiowanie jest dobrą praktyką.

Nie należy ufać konstruktorowi domyślnemu syntetyzowanemu przez kompilator.

Page 38: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 38Strona :

Konstruktor ogólny ― general constructor

A( arg1, arg2, ... );

Konstruktor ogólny:

Jest to podstawowy konstruktor przeznaczony do inicjowania obiektów na etapie ich deklaracji czy też tworzenia.

Argumenty określają zwykle wartości jakie mają być przypisane określonym polom obiektu.

Konstruktorów głównych może być więcej, mogą one zawierać również parametru domyślne.

Szczególnym przypadkiem jest konstruktor posiadający tylko parametry domyślne, staje się on wtedy konstruktorem domyślnym.

A( int a, float b, char * c = NULL );

A obj1( 2, 3.4, "Ala");A obj2( 1, 0.0 );A obj3( 5, 5.5, "Pi ć");ę

Page 39: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 39Strona :

Wiele konstruktorów ogólnych

Rectangle::Rectangle( float width, float height ) : width( width ), height( height ){}

Rectangle::Rectangle( float side ) : width( side ), height( side ){}. . .Rectangle r1( 10, 30), r2( 20 );

Page 40: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 40Strona :

Konstruktor kopiujący ― copy constructor

A( A & obj );A( A & obj, arg1 = wart1, ... );

A( const A & obj );A( const A & obj, arg1 = wart1, ... );

Konstruktor kopiujący:

Jest potrzebny jedynie wtedy, gdy przewidziana jest inicjalizacja obiektu danej klasy innym obiektem tejże klasy:

A obj1;A obj2 = obj1;A obj3( obj2 );

void fun( A obj );

A obj1;fun( obj1 );

A fun( void ){ . . .}

Page 41: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 41Strona :

Konstruktor kopiujący a bitowe kopiowanie pole po polu

1020

widthr1

height1020

widthr2

height

Rectangle r1( 10, 20 );Rectangle r2( r1 );

Kompilator potrafi sobie poradzić z takim przypadkiem. Wykona kopiowanie zawartości obiektu obj1 do obiektów obj2 i obj3 pole po polu, wykonując ich

bitową kopię.

W niektórych przypadkach bitowe kopiowanie pole po polu jest wystarczające. Wtedy programista nie musi definiować konstruktora kopiującego. Tak na prawdę, w klasach Square i Rectangle konstruktor ten nie jest potrzebny.

Page 42: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 42Strona :

Konstruktor kopiujący a bitowe kopiowanie pole po polu

Samochod volvoS80( "Volvo", "S80" );Samochod volvoV50( volvoS80 );

volvoV50.zmienModel( "V50" );

marka

marka

volvoS80

volvoV50

model

model

VolvoS80 V50

volvoV50.zmienModel( "V50" );

Page 43: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 43Strona :

Konstruktor kopiujący a bitowe kopiowanie pole po polu

class A{ public: A() : i( 0 ) { }

private : A( const A & ); int i;};

A a1;A a2( a1 ); // A::A(const A &) is not accessible

Konstruktor kopiujący ― używać, nie używać?

Stosowanie konstruktora kopiującego jest dobrą, programistyczną praktyką. Dzięki jawnie zdefiniowanym konstruktorom programista ma kontrolę nad kopiowaniem wartości, występujących w wielu, czasem zaskakujących sytuacjach.

Można zablokować możliwość inicjowania obiektów, wartością innego obiektu tej samej klasy:

Page 44: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Podsumowanie informacji o konstruktorach Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 44Strona :

Konstruktor rzutujący ― cast, type conversion constructor

Konstruktor rzutujący:

Posiada jeden parametr będący referencją obiektu innej klasy. Innych argumentów może nie być lub powinny być one argumentami domyślnymi.

Jest stosowany wszędzie tam, gdzie należy zainicjować obiekt pewnej klasy wartością obiektu innej klasy.

Programista może dzięki konstruktorowi rzutującemu określić w jaki sposób informacje zapisane w obiekcie klasy B mają zostać odwzorowane (przepisane) w obiekcie klasy A.

A( B & obj );A( const B & obj );

Page 45: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Funkcje inlineFunkcje inline

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 45Strona :

Klasa Rectangle raz jeszcze

Funkcje zdefiniowane wewnątrz definicji klasy są traktowane niejawnie jako funkcje inline (rozwijane w miejscu wywołania).

Funkcje inline nie są wywoływane w sposób klasyczny — ich kod jest umieszczany w miejscu wywołania i w rzeczywistości nie są one wywoływane.

Funkcje inline są preferowanym w C++ zamiennikiem makr definiowanych z wykorzystaniem #define.

class Rectangle{ public : void setWidth( float width ) { Rectangle::width = width; }

float getWidth() const { return width; } . . . };

Page 46: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Funkcje inlineFunkcje inline

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 46Strona :

Jak zadeklarować funkcje jako inline poza zasięgiem deklaracji klasy?

class Rectangle{ public :

. . .

void setWidth( float width ); float getWidth() const;

. . .

};

inline void Rectangle::setWidth( float width ){ Rectangle::width = width;}

inline float Rectangle::getWidth() const{ return width;}

Page 47: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Funkcje inlineFunkcje inline

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 47Strona :

Uwagi na temat funkcji inline

Jeżeli funkcje inline mają być wykorzystywane modułach umożliwiających kompilacje rozłączną, definicja funkcji powinna wystąpić w miejscu jej zwyczajowej deklaracji — w odpowiednim pliku nagłówkowym.

Specyfikacja ze słowem kluczowym inline to tylko rekomendacja dla kompilatora — niektórych funkcji nie można w pełni rozwinąć i będą one wywoływane klasycznie (np. rekurencyjne).

W porównaniu z makrami funkcje inline zapewniają kontrolę typów i wychwytywanie błędów na etapie kompilacji.

Page 48: Wprowadzenie do programowanie w języku C++prac.us.edu.pl/~siminski/po/pjp_cxx_02.pdfWprowadzenie do programowanie w języku C++ Obiekty i klasy Część druga Niniejsze opracowanie

Funkcje inlineFunkcje inline

Podstawy programowania obiektowegoJęzyk C++Język C++Podstawy i języki programowaniaPodstawy i języki programowania

Copyright © Roman Simiński 48Strona :

Kod wielokrotnie wykorzystujący pewną funkcję inline:

Może działać szybciej — brak narzutu czasowego związanego z organizacją wywołania funkcji i powrotu z podprogramu;

Będzie dłuższy, zawiera bowiem rozwinięcia ciała funkcji w miejscu jej każdorazowego wywołania.

Mechanizm funkcji zadeklarowanych jako inline przeznaczony jest do optymalizacji małych, prostych i często wykorzystywanych funkcji.

Dobrym zastosowaniem funkcji inline jest implementacja akcesorów i modyfikatorów realizujących dostęp do prywatnych pól klasy.