Wprowadzenie do programowania w języku C++

prac.us.edu.pl

Wprowadzenie do programowania w języku C++

Wprowadzenie do programowanie

w języku C++

Część druga

Obiekty i klasy

Autor

Roman Simiński

Kontakt

roman.siminski@us.edu.pl

www.us.edu.pl/~siminski

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.


Podstawy i języki programowania

Obiekty i klasy w języku C++

Problem

Język C++

Obiekty i klasy

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.

Koło

Prostokąt

Kwadrat

Trójkąt

Copyright © Roman Simiński Strona : 2


Podstawy i języki programowania

Obiekty i klasy w języku C++

Analiza obiektowa

Język C++

Obiekty i klasy

Stosując zasadę abstrakcji wyodrębniamy najistotniejsze cechy obiektów dla

rozpatrywanego zagadnienia — obliczeń pól figur płaskich.

?

Koło

Prostokąt

Kwadrat

Trójkąt

Copyright © Roman Simiński Strona : 3


Podstawy i języki programowania

Obiekty i klasy w języku C++

Język C++

Obiekty i klasy

Analiza obiektowa — klasa opisu kwadratu Square

Square

Kwadrat

?

side

Modelowany obiekt

Model

implementacyjny

side

Model analityczny

Copyright © Roman Simiński Strona : 4


Podstawy i języki programowania

Obiekty i klasy w języku C++

Język C++

Obiekty i klasy

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;

cout


Podstawy i języki programowania

Obiekty i klasy w języku C++

Stosowanie pól publicznych

Język C++

Obiekty i klasy

Square

+setSide( double newSide )

+getSide()

+area()

-side: double

Copyright © Roman Simiński Strona : 6


Podstawy i języki programowania

Obiekty i klasy w języku C++

Język C++

Obiekty i klasy

Obiekt klasy Square od strony programisty-użytkownika

Deklaracja obiektu s klasy Square:

Square s;

Ustalenie boku o długości 100

s.setSide( 100 );

Obliczenie pola kwadratu:

double p;

p = s.area();

Obliczenie i wyprowadzenie pola kwadratu do stdout:

cout


Podstawy i języki programowania

Obiekty i klasy w języku C++

Język C++

Obiekty i klasy

Szkic programu obliczającego pole kwadratu

#include

using namespace std;

// ???

int main()

{

double num;

Square s;

cout


Podstawy i języki programowania

Obiekty i klasy w języku C++

Deklaracja klasy Square

Język C++

Obiekty i klasy

class Square

{

public :

// Składowe publiczne

void setSide( double newSide );

double getSide();

double area();

private:

};

// Składowe prywatne

double side;

Copyright © Roman Simiński Strona : 9


Podstawy i języki programowania

Obiekty i klasy w języku C++

Język C++

Obiekty i klasy

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


class C

{

private:

// Część prywatna klasy

void privateMethod();


};

private:

// Część prywatna klasy

void privateMethod();

int internalData;

int internalData;

public:

// Część publiczna klasy

void interfaceMethod();

};

Copyright © Roman Simiński Strona : 10


Podstawy i języki programowania

Obiekty i klasy w języku C++

Definicja funkcji składowych

Język C++

Obiekty i klasy

class Square

{

public :

void setSide( double newSide );

double getSide();

double area();

private:

double side;

};

void Square::setSide( double newSide )

{

side = newSide;

}

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.

double Square::getSide()

{

return side;

}

double Square::area()

{

return side * side;

}

Funkcje składowe poza deklaracja klasy

Copyright © Roman Simiński Strona : 11


Podstawy i języki programowania

Obiekty i klasy w języku C++

Definicja funkcji składowych

Język C++

Obiekty i klasy

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

Copyright © Roman Simiński Strona : 12


Podstawy i języki programowania

Konstruktory

Język C++

Obiekty i klasy

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

Square s;

Square squares[ 3 ];

cout


Podstawy i języki programowania

Konstruktory

Rodzaje konstruktorów

Język C++

Obiekty i klasy

Występują cztery rodzaje konstruktorów:

Konstruktor domyślny (ang. default constructor) aktywowany, gdy tworzony

jest obiekt bez jawnie określonych danych inicjalizujących.

Square s, squares[10];

Konstruktor ogólny (ang. general constructor), zwany też parametrowym,

aktywowany gdy tworzymy obiekt z jawnie określonymi danymi inicjalizującymi.

Square s( 100 );

Konstruktor kopiujący (ang. copy constructor) aktywowany wtedy, gdy

tworzymy obiekt, inicjalizując go danymi z innego obiektu tej samej klasy.

Square s( 100 );

Square a = s, b( s );

Konstruktor rzutujący (ang. cast constructor) aktywowany wtedy, gdy tworzymy

obiekt, inicjalizując go danymi z obiektu innej klasy.

Square s( 100 );

Rectangle c = s, d( s );

Copyright © Roman Simiński Strona : 14


Podstawy i języki programowania

Język C++

Konstruktor domyślny ― default constructor

Obiekty i klasy

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;

Square b;

Square c;

Square squares[ 3 ];

// Aktywacja: a.Square()

// Aktywacja: b.Square()

// Aktywacja: c.Square()

// Aktywacja: Square() dla ka dego elementu tablicy:

ż

// squares[ 0 ].Square()

// squares[ 1 ].Square()

// squares[ 2 ].Square()

Copyright © Roman Simiński Strona : 15


Podstawy i języki programowania

Język C++

Konstruktor domyślny ― default constructor

Dwie wersje realizacji konstruktora domyślnego:

Wersja intuicyjna

Square::Square()

{

side = 0;

}

Wersja z listą inicjalizacyjną

Square::Square() : side( 0 )

{

}

Obiekty i klasy



Nazwa pola

Square::Square() : side( 0 )

{

}

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 inicjalizacyjnej

zostanie omówione później.

Copyright © Roman Simiński Strona : 16


Podstawy i języki programowania

Język C++

Konstruktor parametrowy, inaczej ogólny ― general constructor

Obiekty i klasy

Czy można zainicjować obiekt na etapie deklaracji?

Square s( 100 );

cout


Podstawy i języki programowania

Język C++

Konstruktor parametrowy, inaczej ogólny ― general constructor

Obiekty i klasy

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;

};

Copyright © Roman Simiński Strona : 18


Podstawy i języki programowania

Język C++

Konstruktor parametrowy, inaczej ogólny ― general constructor

Obiekty i klasy

Dwie wersje realizacji konstruktora:

Wersja intuicyjna

Square::Square( double startSide )

{

side = startSide;

}

Wersja z listą inicjalizacyjną

Square::Square( double startSide ) : side( startSide )

{

}

Copyright © Roman Simiński Strona : 19


Podstawy i języki programowania

Język C++

Konstruktor parametrowy, inaczej ogólny ― general constructor

Obiekty i klasy

Jak zainicjować obiekt const?

Słowo kluczowe const oznacza, że wartość zmiennej bądź argumentu nie może być

zmieniana w czasie wykonania programu.

const Square cs;

cs.setSide( 1.2 );

// Niezainicjowany obiekt const

// Błąd – próba modyfikacji obiektu const

cout


Podstawy i języki programowania

Operator zakresu w akcji

Język C++

Obiekty i klasy

Wykorzystanie operatora zakresu ::

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

void Square::setSide( double newSide )

{

side = newSide;

}

definiujemy funkcję tak:

void Square::setSide( double side )

{

side = side;

}

To nie będzie działać poprawnie

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

Ale można użyć operatora zakresu:

void Square::setSide( double side )

{

Square::side = side;

}

Copyright © Roman Simiński Strona : 21


Podstawy i języki programowania

Operator zakresu w akcji

Język C++

Obiekty i klasy

Wykorzystanie operatora zakresu ::,cd. ...

Podobny problem występuje w konstruktorze:

Square::Square( double side )

{

side = side;

}

Ten konstruktor nie będzie działał poprawnie

Operator zakresu odsłania przysłonięte pole

Square::Square( double side )

{

Square::side = side;

}

Ten konstruktor będzie działał poprawnie

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

Square::Square( double side ) : side( side )

{

}

Copyright © Roman Simiński Strona : 22


Podstawy i języki programowania

Koncepcja przeciążania funkcji

Język C++

Obiekty i klasy

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

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

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


Podstawy i języki programowania

Funkcje składowe const

Język C++

Obiekty i klasy

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

class Square

{

public :

Square();

Square( double startSide );

Metody ze specyfikacją const nie mogą

modyfikować pól obiektu, mogą zatem

być wywoływane dla obiektów stałych.

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;

}

Copyright © Roman Simiński Strona : 24


Podstawy i języki programowania

Język C++

Konstruktor kopiujący ― copy constructor

Podstawy programowania obiektowego

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.

Copyright © Roman Simiński Strona : 25


Podstawy i języki programowania

Język C++

Konstruktor kopiujący ― copy constructor

Podstawy programowania obiektowego

Najlepiej zdefiniować konstruktor kopiujący

class Square

{

public :

Square();

Square( double side );

Square( Square & otherSquare );

Operator & oznacza referencję,

umieszczony w deklaracji parametru

oznacza przekazanie przez zmienną.

void setSide( double side );

double getSide() const;

double area() const;

private:

double side;

};

Copyright © Roman Simiński Strona : 26


Podstawy i języki programowania

Język C++

Konstruktor kopiujący ― copy constructor

Podstawy programowania obiektowego

Dwie wersje realizacji konstruktora:

Wersja intuicyjna

Square::Square( Square & otherSquare )

{

side = otherSquare.side;

}

Wersja z listą inicjalizacyjną

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

{

}

Copyright © Roman Simiński Strona : 27


Podstawy i języki programowania

Język C++

Konstruktor kopiujący ― copy constructor

Podstawy programowania obiektowego

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


Podstawy i języki programowania

Język C++

Konstruktor kopiujący ― copy constructor

Podstawy programowania obiektowego

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 )

{

}

Copyright © Roman Simiński Strona : 29


Podstawy i języki programowania

Język C++

Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowego

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;

};

Copyright © Roman Simiński Strona : 30


Podstawy i języki programowania

Język C++

Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowego

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;

}

Copyright © Roman Simiński Strona : 31


Podstawy i języki programowania

Język C++

Będzie jeszcze jeden konstruktor...

Podstawy programowania obiektowego

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;

}

Copyright © Roman Simiński Strona : 32


Podstawy i języki programowania

Język C++

Konstruktor rzutujący ― cast constructor

Podstawy programowania obiektowego

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

Square s( 100 );

Rectangle r( s );

// Definicja zainicjowanego kwadratu 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.

Copyright © Roman Simiński Strona : 33


Podstawy i języki programowania

Język C++

Konstruktor rzutujący ― cast constructor

Podstawy programowania obiektowego

Potrzebny jest konstruktor rzutujący

Konstruktor rzutujący odpowiedzialny za skopiowanie zawartości obiektów pewnej

klasy do obiektu innej klasy na etapie inicjalizacji.

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.

Copyright © Roman Simiński Strona : 34


Podstawy i języki programowania

Język C++

Informacja dodatkowa ― parametry domyślne

Podstawy programowania obiektowego

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’

Parametry domyślne dotyczą funkcji składowych klas jak i funkcji niezwiązanych

z klasami.

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 myszą być definiowane od końca listy parametrów.

Prototypy a parametry domyślne

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

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

. . .

void fun( int i, float f, char c )

{

}

Copyright © Roman Simiński Strona : 35


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

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;

A tab[ 10 ];

// Aktywacja: a.A(), b.A(), c.A()

// Aktywacja: A() dla każdego z 10-ciu elementów tab:

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

Copyright © Roman Simiński Strona : 36


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

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.

Copyright © Roman Simiński Strona : 37


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

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

Copyright © Roman Simiński Strona : 38


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

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

Copyright © Roman Simiński Strona : 39


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

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 )

{

. . .

}

Copyright © Roman Simiński Strona : 40


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

Konstruktor kopiujący a bitowe kopiowanie pole po polu

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.

Rectangle r1( 10, 20 );

Rectangle r2( r1 );

r1

r2

width

10

width

10

height

20

height

20

Copyright © Roman Simiński Strona : 41


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

Konstruktor kopiujący a bitowe kopiowanie pole po polu

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

Samochod volvoV50( volvoS80 );

volvoV50.zmienModel( "V50" );

volvoS80

marka

model

Volvo

S80 V50

volvoV50

marka

model

volvoV50.zmienModel( "V50" );

Copyright © Roman Simiński Strona : 42


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

Konstruktor kopiujący a bitowe kopiowanie pole po polu

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:

class A

{

public:

A() : i( 0 )

{

}

private :

A( const A & );

};

int i;

A a1;

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

Copyright © Roman Simiński Strona : 43


Podstawy i języki programowania

Język C++

Podsumowanie informacji o konstruktorach

Podstawy programowania obiektowego

Konstruktor rzutujący ― cast, type conversion constructor

A( B & obj );

A( const B & obj );

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.

Copyright © Roman Simiński Strona : 44


Podstawy i języki programowania

Funkcje inline

Klasa Rectangle raz jeszcze

Język C++

Podstawy programowania obiektowego

class Rectangle

{

public :

void setWidth( float width )

{

Rectangle::width = width;

}

};

float getWidth() const

{

return width;

}

. . .

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.

Copyright © Roman Simiński Strona : 45


Podstawy i języki programowania

Funkcje inline

Język C++

Podstawy programowania obiektowego

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;

}

Copyright © Roman Simiński Strona : 46


Podstawy i języki programowania

Funkcje inline

Uwagi na temat funkcji inline

Język C++

Podstawy programowania obiektowego

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.

Copyright © Roman Simiński Strona : 47


Podstawy i języki programowania

Funkcje inline

Język C++

Podstawy programowania obiektowego

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.

Copyright © Roman Simiński Strona : 48