C++面向对象整理(8)之括号运算符(函数调用符)的重载、仿函数、谓词

C++面向对象整理(8)之括号运算符(函数调用符)的重载、仿函数、谓词

注:整理一些突然学到的C++知识,随时mark一下
例如:忘记的关键字用法,新关键字,新数据结构



提示:本文为 C++ 中 函数调用重载 的写法和举例


一、函数调用()重载与仿函数

1、括号运算符重载

  运算符重载允许程序员为自定义数据类型(如类)重新定义或重载运算符的行为(关于运算符重载)。通过这种方式,我们可以使自定义类型的对象像内置类型(如int、float等)一样使用运算符。当这个运算符是括号的时候,那么重载后就是类的对象可以在紧跟后面加一个括号,十分像函数,所以又称仿函数(functors),它可以把类对象当成函数一样使用

函数调用运算符重载(overloading the function call operator)允许我们定义一个类,使其对象可以像函数那样被调用。这通常通过重载括号operator()来实现。重载后的()允许我们为类定义自己的调用实现,使对象能够像函数那样接收参数并返回结果

2、仿函数

仿函数(也称为函数对象)是重载了函数调用运算符的类的对象。它们的行为类似于函数,但实际上是对象。因为算法通常需要一个可调用对象作为参数,而这个可调用对象可以是函数、函数指针、lambda表达式或仿函数。

3、函数调用运算符重载举例

要重载函数调用运算符,我们需要在类定义中提供一个返回类型,并定义operator(),它可以带任意数量和类型的参数。下面是一个简单的数学加法运算类的例子:

class Add {  
public:  
    int operator()(int a, int b) const {  
        return a + b;  
    }  
};  
  
int main() {  
    Add addObj; // 创建一个Add类型的对象  
    int sum = addObj(3, 4); // 使用对象调用运算符,就像调用函数一样  
    return 0;  
}

在上面的例子中,Add类重载了函数调用运算符,使得我们可以像调用函数一样调用addObj对象,并传入两个整数参数。

4、仿函数的匿名书写方式

仿函数在需要可调用对象的上下文中特别有用,比如STL算法中。由于仿函数本质上是一个类的对象,所以也可以写成匿名对象的形式。

例如,假设我们有一个整数向量,并希望使用仿函数来找到其中的最大值:

#include <vector>  
#include <algorithm>  
#include <iostream>  
  
// 仿函数,用于比较两个整数  
class GreaterThan {  
public:  
    bool operator()(int a, int b) const {  
        return a > b;  
    }  
};  
  
int main() {  
    std::vector<int> numbers = {1, 3, 5, 2, 4};  
      
    // 使用STL的max_element算法和仿函数来找到最大值  
    auto max_it = std::max_element(numbers.begin(), numbers.end(), GreaterThan());  
      
    if (max_it != numbers.end()) {  
        std::cout << "Max element is: " << *max_it << std::endl;  
    }  
      
    return 0;  
}

在这个例子中,GreaterThan是一个比较大小的类,它重载了operator()以比较两个整数。然后,我们使用std::max_element算法和GreaterThan的匿名对象方式的仿函数来找到向量中的最大值。

仿函数的一个优点是它们可以包含状态,这使得它们比普通的函数更加灵活。例如,你可以有一个仿函数,它内部维护一个计数器,每次调用时都递增这个计数器。

5、谓词

注意像上面GreaterThan对其重载的时候返回的是一个bool类,这时又称这个仿函数为谓词。谓词是一个可调用的表达式,其返回结果bool类型是一个能用作条件判断的值。谓词分为一元谓词和二元谓词,一元谓词意味着只接受单一参数,二元谓词意味着接受两个参数。在C++标准库算法中(涉及STL容器与Algorithms),谓词常用于作为参数,以定义元素之间的比较或条件逻辑。常用于STL(标准模板库)算法中,如std::sort、std::find_if等,以提供自定义的比较或条件逻辑。通过定义谓词(仿函数),程序员可以更加灵活地控制这些算法的行为,以满足特定的需求。

谓词约等于仿函数。仿函数是一个重载了函数调用运算符的对象,使其可以像函数那样被调用。当仿函数的返回类型为bool时,它就可以用作谓词。因此,谓词是返回bool类型的仿函数的一种特定用法。

下面举几个使用谓词的例子(提示涉及STL相关):

例子 1: 使用 std::find_if 查找第一个满足条件的元素

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
bool isEven(int n) {  
    return n % 2 == 0; // 谓词:检查一个数是否是偶数  
}  
  
int main() {  
    std::vector<int> numbers = {1, 3, 4, 6, 5, 8};  
      
    // 使用find_if和谓词isEven来查找第一个偶数  
    auto it = std::find_if(numbers.begin(), numbers.end(), isEven);  
      
    if (it != numbers.end()) {  
        std::cout << "The first even number is: " << *it << std::endl;  
    } else {  
        std::cout << "No even numbers found." << std::endl;  
    }  
      
    return 0;  
}

例子 2: 使用 std::remove_if 删除满足条件的元素

#include <iostream>  
#include <vector>  
#include <algorithm>  
#include <iterator>  
  
bool isLessThanFive(int n) {  
    return n < 5; // 谓词:检查一个数是否小于5  
}  
  
int main() {  
    std::vector<int> numbers = {1, 3, 4, 6, 5, 8, 2};  
      
    // 使用remove_if和谓词isLessThanFive来“删除”所有小于5的元素  
    // 注意:remove_if不会真正删除元素,而是将不满足条件的元素移动到容器的末尾,并返回一个迭代器指向新逻辑末尾的位置  
    numbers.erase(std::remove_if(numbers.begin(), numbers.end(), isLessThanFive), numbers.end());  
      
    // 输出修改后的vector  
    for (int num : numbers) {  
        std::cout << num << ' ';  
    }  
    std::cout << std::endl;  
      
    return 0;  
}

例子 3: 使用 std::sort 自定义排序规则

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
// 谓词:用于自定义排序的比较函数  
bool compareStrings(const std::string& a, const std::string& b) {  
    return a.length() < b.length(); // 按字符串长度升序排序  
}  
  
int main() {  
    std::vector<std::string> strings = {"apple", "banana", "cherry", "date"};  
      
    // 使用sort和自定义谓词compareStrings来排序字符串  
    std::sort(strings.begin(), strings.end(), compareStrings);  
      
    // 输出排序后的vector  
    for (const std::string& str : strings) {  
        std::cout << str << ' ';  
    }  
    std::cout << std::endl;  
      
    return 0;  
}

这些例子中,isEven、isLessThanFive和compareStrings都是谓词,它们是返回bool值的函数或仿函数,用于定义特定的条件或比较逻辑。在STL算法中,这些谓词作为参数传递,使得算法能够按照用户定义的方式操作容器中的元素。

总结

  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值