« Funkcje w klasie, czyli metody, lekcja »
Tworzenie metod w klasie oraz ich wywoływanie. (lekcja)
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!
Autor: Piotr Szawdyński
Późniejsze modyfikacje: 'Dante'
Kurs C++

Funkcje w klasie, czyli metody

[lekcja] Tworzenie metod w klasie oraz ich wywoływanie.

Szybki rachunek sumienia

Cała znajomość programowania jaką poznałeś do tej pory sprowadzała się do programowania strukturalnego. Wszystkie funkcje, które pisałeś do tej pory miały zasięg globalny, czyli były widoczne z każdego miejsca w projekcie, co mogło zacząć sprawiać trudności z zapewnieniem unikatowych nazw funkcji dla całego projektu, który pisałeś. Często pewnie zdarzały Ci się również sytuacje, w których tworzyłeś funkcje, do jakich przeciętny użytkownik nie powinien mieć dostępu. Jeśli miałeś takie problemy lub chcesz ich uniknąć w przyszłości rozdział ten pokaże Ci jak można w bardzo prosty sposób je rozwiązywać.

Deklaracja funkcji wewnątrz klasy

Pierwszą, a zarazem najprostszą metodą na utworzenie funkcji w klasie jest napisanie jej wewnątrz klasy. Przykład:
C/C++
class EksperymentCL
{
private:
    int TwojaPrywatnaFunkcja( int a, int b )
    {
        return( a - b + 2 );
    }
public:
    int TwojaPublicznaFunkcja( int a, int b )
    {
        return(( a + b ) * 2 );
    }
};
Funkcje, które zostały zadeklarowane jako publiczne, będą mogły być wywoływane spoza klasy. Funkcje prywatne mogą być wywołane tylko i wyłącznie wewnątrz klasy (we wszystkich funkcjach należących do klasy). Tworzenie funkcji prywatnych jest bardzo wygodne, ponieważ umożliwia nam dzielenie skomplikowanej, zazwyczaj publicznej funkcji na mniejsze elementy, które przy późniejszej analizie i nanoszeniu ewentualnych poprawek sprawia dużo mniej kłopotów niż modyfikacja jednego długiego kodu funkcji.

Definicja funkcji wewnątrz klasy, deklaracja poza klasą

Pierwsza metoda, która została przedstawiona jest bardzo wygodna w użyciu, jednak ma takie same minusy jakie miały funkcje pisane w bloku głównym - kompilator nie widzi funkcji, które są 'wyżej'. Jeśli więc chcielibyśmy wywołać z funkcji TwojaPrywatnaFunkcja(), funkcję TwojaPublicznaFunkcja () to kompilator wyrzuciłby nam błąd. Drugą wadą jest to, że czytelność kodu bardzo się obniża przez to, że nie widać czy dana funkcja należy do klasy czy też nie (nie wspominając o zmiennych). Aby temu zaradzić, ten sam kod co poprzednio można zapisać następująco:
C/C++
class EksperymentCL
{
private:
    int TwojaPrywatnaFunkcja( int a, int b );
public:
    int TwojaPublicznaFunkcja( int a, int b );
};

int EksperymentCL::TwojaPrywatnaFunkcja( int a, int b )
{
    return( a - b + 2 );
}

int EksperymentCL::TwojaPublicznaFunkcja( int a, int b )
{
    return(( a + b ) * 2 );
}

Jak korzystać z funkcji będących wewnątrz klasy w praktyce

Aby skorzystać z funkcji, które są umieszczone wewnątrz klasy, musimy utworzyć sobie najpierw zmienną, a następnie za pomocą utworzonej zmiennej wywołujemy funkcje klasy. Dla powyższego przykładu wyglądałoby to tak:
C/C++
#include <iostream>
#include <conio.h>

using namespace std;

class EksperymentCL
{
private:
    int TwojaPrywatnaFunkcja( int a, int b );
public:
    int TwojaPublicznaFunkcja( int a, int b );
};

int EksperymentCL::TwojaPrywatnaFunkcja( int a, int b )
{
    return( a - b + 2 );
}

int EksperymentCL::TwojaPublicznaFunkcja( int a, int b )
{
    return(( a + b ) * 2 );
}

int main()
{
    EksperymentCL zmienna;
    cout << "Wynik: " << zmienna.TwojaPublicznaFunkcja( 3, 4 ) << endl;
    getch();
    return( 0 );
}
Zaprezentowany przykład jest niezbyt ciekawy, jednak pokazuje on jak działają klasy i funkcje w klasach oraz jak należy z nich korzystać.

Przykład

Poniższy przykład prezentuje praktyczne wykorzystywanie funkcji w klasach.
C/C++
#include <iostream>
#include <iomanip>
#include <string>
#include <conio.h>

using namespace std;
class OsobaCL
{
protected:
    string m_imie;
    string m_nazwisko;
    OsobaCL * m_nastepnaOsoba;
public:
    void Inicjuj();
    void Sprzatnij();
    void Wypelnij();
    OsobaCL * GetNastepnaOsoba();
    void ShowDaneOsoby( int fImieWidth = 12, int fNazwiskoWidth = 20 );
    void DodajOsobeNaKoniec();
};

void OsobaCL::Inicjuj()
{
    m_nastepnaOsoba = NULL;
}

void OsobaCL::Sprzatnij()
{
    if( m_nastepnaOsoba != NULL )
    {
        m_nastepnaOsoba->Sprzatnij();
        delete m_nastepnaOsoba;
        m_nastepnaOsoba = NULL;
    }
}

OsobaCL * OsobaCL::GetNastepnaOsoba()
{
    return( m_nastepnaOsoba );
}

void OsobaCL::Wypelnij()
{
    cout << "Podaj imie: ";
    cin >> m_imie;
    cout << "Podaj nazwisko: ";
    cin >> m_nazwisko;
}

void OsobaCL::ShowDaneOsoby( int fImieWidth, int fNazwiskoWidth )
{
    cout << setw( fImieWidth ) << m_imie << " " << setw( fNazwiskoWidth ) << m_nazwisko << endl;
}

void OsobaCL::DodajOsobeNaKoniec()
{
    //Szukanie ostatniej osoby
    OsobaCL * tOstatniaOsoba = this; //Zapisanie wskaźnika obecnej osoby do zmiennej
    while( tOstatniaOsoba->m_nastepnaOsoba != NULL ) tOstatniaOsoba = tOstatniaOsoba->m_nastepnaOsoba;
   
    //Utworzenie nowej osoby i zapisanie do ostatniej osoby
    OsobaCL * tNowaOsoba = new OsobaCL;
    tNowaOsoba->Inicjuj();
    tNowaOsoba->Wypelnij();
    tOstatniaOsoba->m_nastepnaOsoba = tNowaOsoba;
}

int main()
{
    /*Utworzenie pierwszej osoby*/
    OsobaCL * tPierwszaOsoba = new OsobaCL;
    tPierwszaOsoba->Inicjuj();
   
    /*Wypełnienie pierwszej osoby*/
    tPierwszaOsoba->Wypelnij();
   
    /*Wczytywanie kolejnych osób*/
    char tZnak;
    do
    {
        cout << "Czy chcesz dodac nowa osobe? (T/N) ";
        do
        {
            tZnak = getch();
        } while(( tZnak != 'n' ) &&( tZnak != 'N' ) &&( tZnak != 't' ) &&( tZnak != 'T' ) );
       
        cout << tZnak << endl;
        if(( tZnak == 't' ) ||( tZnak == 'T' ) ) tPierwszaOsoba->DodajOsobeNaKoniec(); //Dodawanie nowej osoby
       
    } while(( tZnak != 'n' ) &&( tZnak != 'N' ) );
   
    /*Wyświetlanie wszystkich osób*/
    OsobaCL * tWyswietlOsoby = tPierwszaOsoba;
    while( tWyswietlOsoby != NULL )
    {
        tWyswietlOsoby->ShowDaneOsoby();
        tWyswietlOsoby = tWyswietlOsoby->GetNastepnaOsoba();
    }
   
    /*Zwalnianie pamięci*/
    tPierwszaOsoba->Sprzatnij();
    delete tPierwszaOsoba;
   
    getch();
    return( 0 );
}
Poprzedni dokumentNastępny dokument
Klasy (obiekty)Konstruktor, destruktor i konstruktor kopiujący klasy