Funkcje OGÓLNE
 

    W dziele funkcje wyjaśniałem czym są funkcje, jak je tworzyć i stosować. W tym dziale wyjaśnię co to są funkcje ogólne. Otóż bardzo często zdarza się, że pisząc program potrzebujemy funkcji która będzie wykonywała operacje na danych różnych typów, jednak nie możemy z góry ustalić jaki to będzie typ. Załóżmy, że potrzebuję funkcji, która będzie dodawała do siebie dwie wartości liczbowe, np.: 1 + 2 i zwracała wynik, więc tworzę mniej więcej taką funkcję:

int zwrot(int x, int y)
{
 return x + y;
}

Proste, ale teraz potrzebuję funkcji, która będzie dodawała do siebie dwie litery i również zwracała wynik, więc żeby to osiągnąć muszę stworzyć taką funkcję:

AnsiString zwrot(String x, String y)
{
 return x + y;
}

Też proste, ale można znacznie prościej, wystarczy stworzyć jedną funkcję ogólną. Funkcję ogólną tworzy się za pomocą słowa kluczowego template, a w odniesieniu do zaprezentowanych wyżej przykładów funkcja będzie wyglądała tak:

template <class T> T zwrot(T x, T y)
{
 return x + y;
};

I w dużym uproszczeniu tak to wygląda, spróbujmy teraz zastosować taką funkcję w praktyce. W tym celu umieszczamy na formularzu cztery obiekty: Edit1, Edit2, Edit3 i Button1, następnie w pliku źródłowym umieszczamy definicję funkcji ogólnej:

// Plik źródłowy np. Unit1.cpp
//--------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
{
}
//--------------------------------
template <class T> T zwrot(T x, T y)
{
 return x + y;
};
//--------------------------------

Teraz w zdarzeniu OnClick dla przycisku Button1 wywołujemy funkcje zwrot i w zależności od tego co będą zawierały obiekty Edit1 i Edit2 wynik zostanie wyświetlony w obiekcie Edit3:

// Plik źródłowy np. Unit1.cpp
//--------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
{
}
//--------------------------------
template <class T> T zwrot(T x, T y)
{
 return x + y;
};
//--------------------------------
void __fastcall TForm1::Button1Click(TObject* Sender)
{
 try
 {
  Edit3->Text = zwrot(Edit1->Text.ToDouble(), Edit2->Text.ToDouble());
 }
 catch(...)
 {
  Edit3->Text = zwrot(Edit1->Text, Edit2->Text);
 }
}
//--------------------------------

No i to wystarczy żeby jedna funkcja obsłużyła różne typy danych, to wiele ułatwia i w przypadku gdy tworzymy duże lub dużo funkcji, zastąpienie ich funkcjami ogólnymi może znacznie przyspieszyć działanie i zmniejszyć rozmiary aplikacji.
    Na koniec gwoli wyjaśnienia, tworząc funkcję ogólną zastosowałem w jej nazwie literę T, ale może to być każda inna litera lub ciąg znaków, po prostu nazwa zastępcza (w przykładzie T) jak również nazwa funkcji (w przykładzie zwrot) są dowolne.

Opracował: Cyfrowy Baron