function object
Főnév
function object (tsz. function objects)
- (informatika) A function object (más néven funktor) egy C++-ban használt speciális objektum, amely úgy viselkedik, mint egy függvény. Ez azt jelenti, hogy az objektumokat lehet úgy hívni, mintha függvények lennének. Ez az operátor
operator()túlterhelésével érhető el.
1. Mi az a Function Object (Funktor)?
Egy funktor egy olyan osztálypéldány, amely az operator() túlterhelésével definiálja a függvényszerű viselkedést. Ez lehetővé teszi, hogy az objektumot függvényként hívjuk meg.
Példa egy egyszerű funktorra:
#include <iostream>
// Funktor osztály
class Osszegzo {
public:
int operator()(int a, int b) {
return a + b;
}
};
int main() {
Osszegzo osszeg;
std::cout << "5 + 3 = " << osszeg(5, 3) << std::endl; // 5 + 3 = 8
return 0;
}
Mi történik itt?
- Az Osszegzo osztály definiál egy operator()() függvényt.
- Az osszeg nevű példány úgy hívható meg, mintha függvény lenne: osszeg(5, 3).
- A funktor így egy paraméterezhető, függvényszerű viselkedést biztosító objektum.
2. Miért Használunk Funktorokat?
A funktoroknak több előnyük van a hagyományos függvényekhez képest:
- Állapotmegőrzés:
- A funktorok osztálytagokat (változókat) is tárolhatnak, így állapotot tarthatnak fenn.
- Hatékonyabb optimalizáció:
- A kompilátor jobban tudja optimalizálni őket, mint a sima függvénymutatókat.
- Testreszabhatóság és újrafelhasználhatóság:
- Az
operator()túlterhelésével bonyolultabb működést lehet beépíteni.
- Az
- STL-ben való használat:
- A funktorokat gyakran használják az STL algoritmusokkal, például
std::sort,std::for_each.
- A funktorokat gyakran használják az STL algoritmusokkal, például
3. Funktorok Állapottal
A funktorok képesek állapotot tárolni, ami azt jelenti, hogy az objektum memóriában megőrzi az előző állapotát.
#include <iostream>
class Szorzo {
private:
int faktor;
public:
Szorzo(int f) : faktor(f) {}
int operator()(int x) {
return x * faktor;
}
};
int main() {
Szorzo duplazo(2);
Szorzo haromszorozo(3);
std::cout << "5 * 2 = " << duplazo(5) << std::endl; // 10
std::cout << "5 * 3 = " << haromszorozo(5) << std::endl; // 15
return 0;
}
Itt:
- A Szorzo osztály egy számot (faktor) tárol.
- A operator() minden híváskor megszorozza a bemenetet ezzel az értékkel.
Ez a fajta állapotmegőrzés nem érhető el normál függvényekkel.
4. STL és Funktorok
A funktorokat gyakran használják az STL algoritmusokkal. Például az std::sort-tal együtt:
#include <iostream>
#include <vector>
#include <algorithm>
// Csökkenő rendezést végző funktor
class CsokkenoRendezes {
public:
bool operator()(int a, int b) {
return a > b; // Csökkenő sorrend
}
};
int main() {
std::vector<int> szamok = {3, 1, 4, 1, 5, 9};
std::sort(szamok.begin(), szamok.end(), CsokkenoRendezes());
for (int szam : szamok) {
std::cout << szam << " ";
}
return 0;
}
Magyarázat:
- Az std::sort normálisan növekvő sorrendben rendezi az elemeket.
- A CsokkenoRendezes funktorral megfordíthatjuk a sorrendet.
5. Beépített Funktorok az STL-ben
A C++ STL (Standard Template Library) számos beépített funktort tartalmaz az #include <functional> fejléccel.
Példa az std::greater<int> használatára csökkenő rendezéshez:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // Szükséges a beépített funktorokhoz
int main() {
std::vector<int> szamok = {3, 1, 4, 1, 5, 9};
std::sort(szamok.begin(), szamok.end(), std::greater<int>());
for (int szam : szamok) {
std::cout << szam << " ";
}
return 0;
}
Ez ugyanazt éri el, mint a korábbi CsokkenoRendezes funktor, de nem kell saját osztályt írnunk.
Gyakori beépített funktorok:
| Funktor | Leírás | |———|——–| | std::plus<T> | Összeadás | | std::minus<T> | Kivonás | | std::multiplies<T> | Szorzás | | std::divides<T> | Osztás | | std::modulus<T> | Maradékos osztás | | std::negate<T> | Negáció | | std::greater<T> | Nagyobb összehasonlítás | | std::less<T> | Kisebb összehasonlítás | | std::equal_to<T> | Egyenlőségvizsgálat | | std::not_equal_to<T> | Nem egyenlőségvizsgálat |
6. Lambda Kifejezések vs. Funktorok
A C++11 bevezetett egy modernebb alternatívát: lambda kifejezések.
Példa funktor helyett lambdával:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> szamok = {3, 1, 4, 1, 5, 9};
std::sort(szamok.begin(), szamok.end(), [](int a, int b) {
return a > b;
});
for (int szam : szamok) {
std::cout << szam << " ";
}
return 0;
}
Ez a lambda kifejezés egyszerűbb és rövidebb, mint egy külön funktor osztály létrehozása.
Mikor érdemes funktort használni a lambdák helyett?
- Ha az állapotot meg kell őrizni az objektumban.
- Ha a kód újrafelhasználhatósága fontos.
- Ha a függvény nagyon komplex és többször kell használni.
Összegzés
- A function object (funktor) egy osztály, amely túlterheli az
operator()()-t, így függvényszerűen hívható.
- Használható állapot megőrzésére, STL algoritmusokkal, és hatékonyabb optimalizációt tesz lehetővé.
- A C++ STL számos beépített funktort kínál (
std::greater,std::plusstb.).
- Lambda kifejezések sok esetben kiváltják a funktorokat, de azok továbbra is hasznosak bizonyos esetekben.
- function object - Szótár.net (en-hu)
- function object - Sztaki (en-hu)
- function object - Merriam–Webster
- function object - Cambridge
- function object - WordNet
- function object - Яндекс (en-ru)
- function object - Google (en-hu)
- function object - Wikidata
- function object - Wikipédia (angol)