C++_Klasy.doc

(82 KB) Pobierz
Tematyka i cel ćwiczenia

JEZYK C++, KLASY – POJECIA PODSTAWOWE              6

Tematyka i cel ćwiczenia.

Celem ćwiczenia jest zapoznanie z podstawowym elementem języka C++ – klasą. Wprowadzone są następujące pojęcia: klasa, konstruktor(y) klasy, destruktor klasy, metody klasy, operatory new oraz delete wykorzystywane do alokacji i usuwania obiektów z pamięci oraz funkcje zaprzyjaźnione z klasą.

Wymienione wyżej pojęcia są zilustrowane na przykładzie klasy implementującej strukturę danych typu stos.

Wprowadzenie.

Celem wprowadzenia pojęcia klasy do języka C++ jest dostarczenie programiście narzędzia do tworzenia nowych typów, z których można korzystać tak samo wygodnie, jak z typów wbudowanych do języka. Typ zdefiniowany przez użytkownika nie powinien się różnić od typu wbudowanego sposobem używania, lecz tylko sposobem tworzenia go.

Deklaracja klasy zawiera jedno z trzech słów kluczowych class, struct lub union poprzedzających nazwę klasy i następnie deklarację poszczególnych pól danych i funkcji składowych (metod) zawartych w nawiasach klamrowych.

Na przykład:

struct abc {

              int x;

              double *d;

              abc();

              abc(int ax, double ad);

              ~abc();

              void fun1(void);

              int fun2(int x);

              int fun2(double x);

};

W powyższym przykładzie zadeklarowano klasę o nazwie abc zawierającą dwa pola danych: jedno typu int, drugie typu double* oraz 6 metod:

·            abc()              – konstruktor 1,

·            abc(int, double)              – konstruktor 2,

·            ~abc()              – destruktor,

·            void fun1(void)              – metoda fun1,

·            int fun2(int)              – metoda 1. fun2,

·            int fun2(double)              – metoda 2. fun2,

Szczególną rolę pełnią metody zwane konstruktorem klasy i destruktorem klasy.

Konstruktorem(ami) klasy jest metoda o nazwie identycznej z nazwą klasy. Jest ona wywoływana automatycznie przez kompilator w chwili tworzenia klasy i ma na celu jej zainicjowanie. Konstruktorów może być kilka (to znaczy mogą być przeciążane), przy czym muszą się one między sobą różnić typami argumentów (podobnie jak funkcje przeciążone). Konstruktor nie może zwracać żadnej wartości (nawet typu void).

Destruktorem klasy jest metoda o nazwie identycznej z nazwą klasy poprzedzoną znakiem „~”. W danej klasie może być tylko jeden destruktor. Musi być on metodą bez żadnych argumentów i nie może zwracać żadnej wartości (nawet typu void). Destruktor jest wywoływany automatycznie w chwili usuwania klasy z pamięci.

Jeżeli w definicji klasy zostanie użyte słowo kluczowe struct (tak jak w przykładzie), wtedy wszystkie elementy klasy (pola danych i metody) są domyślnie dostępne na zewnątrz klasy – inaczej mówiąc są publiczne.

Jeżeli w definicji klasy zostanie użyte słowo kluczowe class, wtedy wszystkie elementy klasy (pola danych i metody) nie są domyślnie dostępne na zewnątrz klasy – inaczej mówiąc są prywatne.

W celu zmiany praw dostępu do poszczególnych elementów klasy można użyć następujących słów kluczowych:

·            public – powodującego, że wszystkie następne elementy klasy są publiczne (dostępne na zewnątrz klasy i we wszystkich klasach pochodnych),

·            private – powodującego, że wszystkie następne elementy klasy są prywatne (nie dostępne na zewnątrz klasy i w klasach pochodnych),

·            protected – powodującego, że wszystkie następne elementy klasy są zastrzeżone (nie dostępne na zewnątrz klasy, ale są dostępne w klasach pochodnych).

Użycie wyżej wymienionych słów ilustrują przykłady poniżej.

struct abc1 {

              int x;                                                                      // public (domyślnie)

private:

              double *d;                                                        // private

public:

              abc1();                                                                      // public

              abc1(int ax, double ad);              // public

              ~abc1();                                                                      // public

              void fun1(void);                                          // public

private:

              int fun2(int x);                                          // private

public:

              int fun2(double x);                            // public

};

 

class abc2 {

              int x;                                                                      // private (domyślnie)

              double *d;                                                        // private (domyślnie)

public:

              abc2();                                                                      // public

              abc2(int ax, double ad);              // public

              ~abc2();                                                                      // public

              void fun1(void);                                          // public

private:

              int fun2(int x);                                          // private

public:

              int fun2(double x);                            // public

};

Funkcją zaprzyjaźnioną z daną klasą jest funkcja nie będąca funkcją składową danej klasy lecz mająca dostęp do prywatnych (private) i zastrzeżonych (protected) elementów klasy. Funkcję zaprzyjaźnione nie są składowymi klasy. W związku z tym nie mają one dostępu do wskaźnika this, dzięki któremu mogłyby identyfikować obiekt (instancję klasy), na której dana funkcja ma operować. Z tego powodu najczęściej jednym z argumentów funkcji zaprzyjaźnionych jest wskaźnik lub referencja do klasy, na której funkcja ma operować. Funkcja zaprzyjaźniona musi być zadeklarowana wewnątrz klasą, z którą ma być zaprzyjaźniona. Jej deklaracja jest poprzedzona słowem kluczowym friend.

Przykład deklaracji funkcji zaprzyjaźnionej jest pokazany poniżej.

class abc4 {

              int x;

              double *d;

public :

              abc4();

              abc4(int ax, double ad);

              ~abc4();

              void fun1(void);

              friend int fun2(abc4 &A, int x);

              friend int fun2(abc4 &A, double x);

};

 

int fun2(abc4 &A, int x)

{

              // definicja funkcji

}

 

int fun2(abc4 &A, double x)

{

              // definicja funkcji

}

Do ćwiczenia należy zapoznać się z literatury z następującymi pojęciami:

·            klasa, definicja klasy, konstruktor(y) klasy, destruktor klasy, metody klasy, wskaźnik this, dostęp do składowych klasy,

·            funkcje zaprzyjaźnione,

·            operatory new i delete.

Z literatury można polecić następujące książki:

·            B. Stroustrup „Język C++”,

·            S. Lipmann „Podstawy języka C++”.

 


Program ćwiczenia

Wstęp



Stos (ang. stack) jest liniową strukturą danych dostępnych do zapisywania i odczytywania tylko z jednego końca. Z tego powodu stos jest nazywany strukturą typu LIFO (Last In First Out). W praktyce stos można zaimplementować za pomocą jednowymiarowej tablicy s oraz wskaźnika stosu sp wskazującego indeks kolejnej wolnej komórki tablicy. Implementacja taka jest przedstawiona na rysunku 1.

Operacja wprowadzania elementu na stos polega na przypisaniu wartości tego elementu komórce tablicy s wskazywanej przez wskaźnik sp, a następnie na zwiększeniu tego wskaźnika o 1 tak, aby wskazywał on następną wolną komórkę. Implementacja funkcji wprowadzania na stos nie może dopuścić do przepełnienia stosu tj. zapisywania poza granicami tablicy.

Pobieranie elementu ze stosu polega na zmniejszeniu wskaźnika sp o 1 i odczytaniu wartości komórki tablicy s wskazywanej przez wskaźnik stosu sp. Implementacja funkcji odczytującej kolejne elementy z wierzchołka stosu nie może zmniejszać wskaźnika stosu jeśli stos jest pusty.

Jeżeli wskaźnik stosu ma wartość n – oznacza to, że stos jest pełny.

Jeżeli wskaźnik stosu wskazuje element o indeksie 0 – oznacza to, że stos jest pusty.

Dany jest następujący szkielet programu:

#include <string.h>

#include <stdio.h>

 

class Stack {

              private:

                            int *s;

                            int size, sp;

              public:

                            Stack(int ASize);

                            Stack(Stack &As);

                            ~Stack();

                            void push(int Ax);

                            int pop(void);

                            int free(void);

                            int empty(void);

                            int full(void);

};

/* -------------------------------------------------------- */

/*

tutaj należy zdefiniować kostruktory, destruktor i metody klasy Stack.

*/

 

/* -------------------------------------------------------- */

 

main()

{

              class Stack ss1(10);

              int x, koniec = 0;

              char c;

 

              while(!koniec) {

              printf("%c STOS(%d) ", ss1.empty() ? 'E' : ss1.full() ?

                            'F' : ' ', ss1.free());

                            scanf("%c", &c);

                            switch(c) {

                                          case '<' :              scanf("%d", &x);

                                                                                    ss1.push(x);

                                                                                    break;

                                          case '>'...

Zgłoś jeśli naruszono regulamin