C++ Funktorlar (Funksiya obyektlari)
C++ funktori (funksiya ob'ekti) - bu funksiya kabi chaqirilishi mumkin bo'lgan sinf yoki struktura ob'ekti.
U () funksiya chaqiruv operatorini haddan tashqari yuklaydi va bizga funksiya kabi ob'ektdan foydalanish imkonini beradi.
Biz C++ da funktor yaratishimiz mumkin:
class Greet {
public:
void operator()() {
// funksiya tanasi
}
};
Bu erda biz () funksiyasini chaqirish operatorini ortiqcha yuklaymiz. Bu bizga sinf ob'ektini quyida ko'rsatilgandek funksiya sifatida chaqirish imkonini beradi:
// Greet misolini yarating
Greet greet;
// ob'ektni funksiya sifatida chaqiring
greet();
[!NOTE] Sinf uchun
()operatorini haddan tashqari yuklashdapublickirish spetsifikatsiyasini o'rnatishni unutmang, chunki sukut bo'yicha sinf a'zolariprivatedir.
#include <iostream>
using namespace std;
class Greet {
public:
// haddan tashqari yuk funksiyasi chaqiruvi/qavslar operatori
void operator()() {
cout << "Hello World!";
}
};
int main() {
// Greet sinfining ob'ektini yarating
Greet greet;
// ob'ektni funksiya sifatida chaqiring
greet();
return 0;
}
Chiqish
Hello World!
Yuqoridagi misolda biz C++ funktorlari yordamida Hello World! ni chop etuvchi oddiy dastur yaratdik.
Funktor yaratish uchun avvalo obyektini funksiya deb atashimiz mumkin bo‘lgan sinf yaratishimiz kerak. Shunday qilib, biz Greet nomli sinf yaratdik.
Greet sinfi ichida
Bu erda biz () funksiyasini chaqirish operatorini haddan tashqari yukladik:
class Greet {
public:
// ortiqcha yuk funksiyasi chaqiruv operatori
void operator()() {
cout << "Hello World!";
}
};
Bu yerda, bizning haddan tashqari yuklangan funksiya shunchaki Hello World! ni chop etadi.
Asosiy() funksiyasi ichida
Bu erda biz Greet sinfidan greet deb nomlangan ob'ektni yaratdik.
Greet greet;
Endi () operatori yordamida salomlashish obyektini chaqiramiz:
// "Salom dunyo!"
greet()
Shu bilan bir qatorda, salomlashishni quyidagi kod yordamida chaqirishimiz mumkin:
// "Salom dunyo!"
greet.operator()();
Parametrlarni qabul qiluvchi va qiymat qaytaruvchi funktorni ham belgilashimiz mumkin. Masalan,
#include <iostream>
using namespace std;
class Add {
public:
// ortiqcha yuk funksiyasi chaqiruv operatori
// ikkita tamsayı argumentini qabul qiling
// ularning summasini qaytaring
int operator() (int a, int b) {
return a + b;
}
};
int main() {
// Add sinfining ob'ektini yarating
Add add;
// qo'shish ob'ektiga qo'ng'iroq qiling
int sum = add(100, 78);
cout << "100 + 78 = " << sum;
return 0;
}
Chiqish
100 + 78 = 178
Yuqoridagi misolda biz ularning yig'indisini topish uchun butun sonni qaytarish turi va ikkita butun parametrli funktordan foydalanganmiz.
class Add {
public:
int operator()(int a, int b) {
return a + b;
}
};
main() ichida biz Add sinfidan qo'shish ob'ektini yaratdik.
Keyin, biz 100 va 78 parametrlari bilan add ob'ektini chaqirdik. Funktordan qaytariladigan qiymat sum o'zgaruvchisiga tayinlanadi.
// 178 ni qaytaradi
int sum = add(100, 78);
#include<iostream>
using namespace std;
class Add_To_Sum {
private:
int initial_sum;
public:
//
Add_To_Sum(int sum) {
initial_sum = sum;
}
// ortiqcha yuk funksiyasi chaqiruv operatori
int operator()(int num) {
return initial_sum + num;
}
};
int main() {
// Add_To_Sum sinfining ob'ektini yarating
// ob'ektning a'zo o'zgaruvchisini 100 qiymati bilan ishga tushiring
Add_To_Sum add = Add_To_Sum(100);
// qo'shish ob'ektini argument sifatida 78 bilan chaqiring
int final_sum = add(78);
cout << "100 + 78 = " << final_sum;
return 0;
}
Chiqish
100 + 78 = 178
Yuqoridagi misolda Add_To_Sum sinfida initial_sum a'zo o'zgaruvchisi mavjud. Biz ushbu o'zgaruvchini konstruktor yordamida ishga tushirdik:
//
Add_To_Sum(int sum) {
initial_sum = sum;
}
Keyin biz funksiyani chaqirish operatorini haddan tashqari yukladik:
int operator()(int num) {
return initial_sum + num;
}
main() da biz parametrlangan konstruktor yordamida add ob'ektining initial_sum o'zgaruvchisini 100 ga ishga tushirdik:
// initial_sum o'zgaruvchisini 100 ga ishga tushiring
Add_To_Sum add = Add_To_Sum(100);
Nihoyat, biz funktorni chaqirdik va argument sifatida 78 ni o'tkazdik.
// 100 va 78 summasini qaytaradi, ya'ni 178
int final_sum = add_to_100(78);
functional sarlavha faylini qo'shish orqali standart kutubxona tomonidan taqdim etilgan oldindan belgilangan funktorlardan foydalanishimiz mumkin:
#include <functional>
C++ arifmetik, relyatsion va mantiqiy amallar uchun quyidagi kutubxona funktorlarini taqdim etadi.
Funktorlar tavsifi plus ikki parametrning yig‘indisini qaytaradi minus ikki parametrning farqini qaytaradi multiplies ikki parametrning mahsulotini qaytaradi divides ikkita parametrga bo‘lingandan so‘ng natijani qaytaradi modulus ikkita parametrga bo‘lingandan keyin qolganni qaytaradi negate a parametrining inkor etilgan qiymatini qaytaradi
Funktorlar tavsifi equal_to true ni qaytaradi, agar ikkita parametr teng bo'lsa not_equal_to , agar ikkita parametr teng bo'lmasa, not_equal_to true ni qaytaradi, agar birinchi parametr ikkinchidan katta bo'lsa greater true ni qaytaradi, agar birinchi parametr ikkinchi parametrdan katta yoki unga teng bo'lsa, greater_equal true ni qaytaradi, agar birinchi parametr ikkinchidan katta yoki birinchi parametrdan kichik bo'lsa XCODEX ikkinchi parametrdan kichik bo'lsa. Agar birinchi parametr ikkinchidan kichik yoki unga teng bo'lsa, less_equal true ni qaytaradi
Funktorlar tavsifi logical_and ikkita mantiqiy qiymatning Mantiqiy VA ishlashi natijasini qaytaradi logical_or ikkita mantiqiy qiymatning Mantiqiy YOKI ishlashi natijasini qaytaradi logical_not mantiqiy EMAS mantiqiy natijasini qaytaradi
Funktorlar tavsifi bit_and Bitwise VA ikkita parametrning ishlashi natijasini qaytaradi bit_or Bitwise OR ikki parametrning ishlashi natijasini qaytaradi bit_xor ikkita parametrning Bitwise XOR ishlashi natijasini qaytaradi
Odatda funktorlar C++ STL bilan sort , count_if , all_of va boshqalar kabi STL algoritmlariga argument sifatida ishlatiladi.
Ushbu misolda biz oldindan belgilangan greater<T>() C++ funksiyasini ko'rib chiqamiz, bu erda T STL algoritmi sort bilan funktor parametrining turidir.
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
int main() {
// int vektorini ishga tushirish
vector<int> nums = {1, 20, 3, 89, 2};
// vektorni kamayish tartibida tartiblang
sort(nums.begin(), nums.end(), greater<int>());
for(auto num: nums) {
cout << num << ", ";
}
return 0;
}
Chiqish
89, 20, 3, 2, 1
Yuqoridagi misolda biz butun sonlar vektorini (sonlar deb ataladi) kamayish tartibida tartiblash uchun oldindan belgilangan funktordan foydalanganmiz.
Odatiy bo'lib, sort() funksiyasi elementlarni o'sish tartibida tartiblaydi.
Uni kamayish tartibida tartiblash uchun biz oldindan belgilangan greater<T> funktoridan foydalandik.
sort(nums.begin(), nums.end(), greater<int>());
E'tibor bering, biz greater<int>() kodidan foydalanganmiz. Buning sababi, sonlar butun vektor, shuning uchun biz T o'rniga int dan foydalanamiz.
Nihoyat, biz for diapazoni yordamida tartiblangan vektorni chop etamiz.
Tez-tez so'raladigan savollar #include <iostream> using namespace std; struct Greet { // overload function call/parentheses operator void operator()() { cout << "Hello World!"; } }; int main() { // create a variable of Greet struct Greet greet; // call the struct variable as a function greet(); return 0; } chiqishi Salom dunyo! Yuqoridagi misolda biz Greet nomli struct yaratdik va Hello World! ni chop etish uchun () operatorini ortiqcha yukladik. main() da biz Greet o'zgaruvchisini yaratdik va () operatori yordamida funktorni chaqirdik: Greet greet; // Output: Hello World! greet(); #include <iostream> #include <vector> #include <algorithm> using namespace std; class Even_Counter { public: // overload function call operator // returns true if the n is even bool operator()(int n) { return n % 2 == 0; } }; int main() { // initialize vector of integers vector<int> nums = {1, 2, 3, 4, 5, 8, 10, 12}; // create an object of Even_Counter Even_Counter even_counter; // count the number of even numbers in the vector int even_count = count_if(nums.begin(), nums.end(), even_counter); cout << "There are " << even_count << " even numbers."; return 0; } Chiqish 5 ta juft son mavjud. Yuqoridagi misolda biz vector raqamlaridagi umumiy juft sonlarni hisoblash uchun count_if STL algoritmiga ega maxsus funktordan foydalandik. Biz Even_Counter nomli sinfni yaratdik va agar raqam juft bo'lsa, true ni qaytarish uchun funksiya chaqiruvi operatorini ortiqcha yukladik. bool operator()(int n) { return n % 2 == 0; } main() da biz nums nomli vector butun sonini va even_counter nomli Even_Counter obyektini yaratdik. Keyin, sonlarda juft butun sonlar sonini hisoblash uchun count_if algoritmidan foydalanamiz: int even_count = count_if(nums.begin(), nums.end(), even_counter); count_if ga uchinchi argument sifatida even_counter funktorini o'tkazganimizga e'tibor bering. even_counter funktori joriy vektor elementni n argumenti sifatida qabul qiladi va agar n juft bo'lsa, true ni qaytaradi. Funksiyani chaqirish operatorini tur parametrlari bilan ortiqcha yuklash orqali umumiy funktor yaratishimiz mumkin. Buning uchun biz class templates dan foydalanishimiz kerak. #include <iostream> #include <algorithm> #include <vector> using namespace std; template<typename T> class Greater_Than { public: // returns true if left is greater than right bool operator()(const T &left, const T &right) { return left > right; } }; int main() { // initialize vector of int vector<int> int_nums = {1, 20, 3, 89, 2}; // sort the vector in descending order sort(int_nums.begin(), int_nums.end(), Greater_Than<int>()); for(auto num: int_nums) { cout << num << ", "; } return 0; } Chiqish 89, 20, 3, 2, 1 Yuqoridagi misolda biz C++ da oldindan belgilangan greater<int> funksiyasiga o'xshash ishlaydigan Greater_Than<T> funktorini joriy qildik. Odatiy bo'lib, STL sort() funksiyasi elementlarni o'sish tartibida tartiblaydi. Inside Greater_Than Class: template<typename T> class Greater_Than { public: bool operator()(const T &left,const T &right) { return left > right; } }; Inside main() Funksiya: Biz int_nums butun vektorini ishga tushirdik. Keyin vektorni STL sort() funksiyasidan foydalanib tartiblaymiz. // vektorni kamayish tartibida tartiblash sort(int_nums.begin(), int_nums.end(), Katta_tana<int>()); E'tibor bering, biz Greater_Than sinfining ob'ektini yaratmadik, lekin Greater_Than<int>() ni funksiya ob'ektini yaratuvchi uchinchi argument sifatida topshirdik. Bu quyidagilarga teng: Greater_Than<int> greater_than; // sort the vector in descending order sort(int_nums.begin(), int_nums.end(), greater_than);