background image

 

 

Wprowadzenie do programowanie 

Wprowadzenie do programowanie 

obiektowego w języku C++

obiektowego 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

roman.siminski@us.edu.pl
www.us.edu.pl/~siminski

Autor

Kontakt

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

2

Strona :

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ło

Prostokąt

Trójkąt

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

3

Strona :

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

?

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

4

Strona :

Analiza obiektowa — klasa opisu kwadratu Square

Kwadrat

side

Square

?

side

Modelowany obiekt

Model analityczny

Model 

implementacyjny

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

5

Strona :

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

.

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Stosowanie pól publicznych

Square

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

-side: double

Copyright © Roman Simiński

6

Strona :

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

7

Strona :

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:

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

8

Strona :

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;
}

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

9

Strona :

Deklaracja klasy Square

class Square
{
  public :

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

  private:

    // Składowe prywatne
    double side;
};

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

10

Strona :

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();
};

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

11

Strona :

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.

background image

 

 

Obiekty i klasy w języku C++

Obiekty i klasy w języku C++

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

12

Strona :

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

background image

 

 

Konstruktory

Konstruktory

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

13

Strona :

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 automatycznie
w 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.

background image

 

 

Konstruktory

Konstruktory

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

14

Strona :

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 );

background image

 

 

Konstruktor domyślny 

Konstruktor domyślny 

 default constructor

 default constructor

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

15

Strona :

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()

background image

 

 

Konstruktor domyślny 

Konstruktor domyślny 

 default constructor

 default constructor

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

16

Strona :

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ąca

konstruktora

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.

background image

 

 

Konstruktor parametrowy, inaczej ogólny 

Konstruktor parametrowy, inaczej ogólny 

 general constructor

 general constructor

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

17

Strona :

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 

background image

 

 

Konstruktor parametrowy, inaczej ogólny 

Konstruktor parametrowy, inaczej ogólny 

 general constructor

 general constructor

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

18

Strona :

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;
};

background image

 

 

Konstruktor parametrowy, inaczej ogólny 

Konstruktor parametrowy, inaczej ogólny 

 general constructor

 general constructor

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

19

Strona :

Dwie wersje realizacji konstruktora:

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

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

Wersja intuicyjna

Wersja z listą inicjalizacyjną

background image

 

 

Konstruktor parametrowy, inaczej ogólny 

Konstruktor parametrowy, inaczej ogólny 

 general constructor

 general constructor

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

20

Strona :

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

background image

 

 

Operator zakresu w akcji

Operator zakresu w akcji

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

21

Strona :

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 

background image

 

 

Operator zakresu w akcji

Operator zakresu w akcji

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

22

Strona :

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

background image

 

 

Koncepcja przeciążania funkcji

Koncepcja przeciążania funkcji

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

23

Strona :

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 )

.

background image

 

 

Funkcje składowe const

Funkcje składowe const

Obiekty  i klasy

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

24

Strona :

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.

background image

 

 

Konstruktor kopiujący 

Konstruktor kopiujący 

 copy constructor

 copy constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

25

Strona :

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.

background image

 

 

Konstruktor kopiujący 

Konstruktor kopiujący 

 copy constructor

 copy constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

26

Strona :

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ą.

background image

 

 

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

Konstruktor kopiujący 

Konstruktor kopiujący 

 copy constructor

 copy constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

27

Strona :

Dwie wersje realizacji konstruktora:

Wersja intuicyjna

Wersja z listą inicjalizacyjną

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

background image

 

 

Konstruktor kopiujący 

Konstruktor kopiujący 

 copy constructor

 copy constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

28

Strona :

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

ą

background image

 

 

Konstruktor kopiujący 

Konstruktor kopiujący 

 copy constructor

 copy constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

29

Strona :

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 )

{
}

background image

 

 

Będzie jeszcze jeden konstruktor...

Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

30

Strona :

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;
};

background image

 

 

Będzie jeszcze jeden konstruktor...

Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

31

Strona :

Definicja konstruktorów i realizatora

// Konstruktor domy lny

ś

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

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

// Konstruktor kopiuj cy

ą

Rectangle::Rectangle( const Rectangle & otherRectangle )
: width( otherRectangle.width ), height( otherRectangle.height )
{
}

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

background image

 

 

Będzie jeszcze jeden konstruktor...

Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

32

Strona :

Definicja modyfikatorów i realizatorów

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

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

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

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

background image

 

 

Konstruktor rzutujący 

Konstruktor rzutujący 

 cast constructor

 cast constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

33

Strona :

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

Square s( 100 );

// Definicja zainicjowanego kwadratu s

Rectangle 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

background image

 

 

Konstruktor rzutujący 

Konstruktor rzutujący 

 cast constructor

 cast constructor

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

34

Strona :

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. 

background image

 

 

Informacja dodatkowa 

Informacja dodatkowa 

 parametry domyślne

 parametry domyślne

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

35

Strona :

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ązanych
z 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ą.

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

36

Strona :

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... .

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

37

Strona :

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.  

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

38

Strona :

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 ć");

ę

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

39

Strona :

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 );

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

40

Strona :

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 )
{
  . . .
}

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

41

Strona :

Konstruktor kopiujący a bitowe kopiowanie pole po polu

10

20

width

r1

height

10

20

width

r2

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.

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

42

Strona :

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

Volvo

S80 V50

volvoV50.zmienModel( "V50" );

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

43

Strona :

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:

background image

 

 

Podsumowanie informacji o konstruktorach 

Podsumowanie informacji o konstruktorach 

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

44

Strona :

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 );

background image

 

 

Funkcje inline

Funkcje inline

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

45

Strona :

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;
    }
    . . . 
};

background image

 

 

Funkcje inline

Funkcje inline

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

46

Strona :

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;
}

background image

 

 

Funkcje inline

Funkcje inline

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

47

Strona :

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.

background image

 

 

Funkcje inline

Funkcje inline

Podstawy programowania obiektowego

Język C++

Język C++

Podstawy i języki programowania

Podstawy i języki programowania

Copyright © Roman Simiński

48

Strona :

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łychprostych 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.


Document Outline