C++函数对象(也称为仿函数或functor)是一种可以像函数一样被调用的对象
- 作为参数传递给其他函数:函数对象可以作为参数传递给STL算法,例如sort()、for_each()、transform()等。这使得算法更加灵活,因为你可以传递不同的函数对象来实现不同的操作。
std::vectorvec = {3, 1, 4, 1, 5, 9}; std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; }); // 使用lambda表达式作为函数对象
- 实现回调函数:函数对象可以作为回调函数传递给事件处理程序或其他需要回调函数的场景。这使得代码更加模块化,因为你可以将特定的操作封装在一个函数对象中,并在需要时将其传递给其他代码。
class Button {
public:
void onClick(std::function<void()> callback) {
// 当按钮被点击时,调用回调函数
callback();
}
};
Button button;
button.onClick([]() {
std::cout << "Button clicked!" << std::endl;
}); // 使用lambda表达式作为回调函数
- 实现适配器模式:函数对象可以用作适配器,将一个类的接口转换为另一个类所期望的接口。这使得你可以将现有的类与新的接口一起使用,而无需修改原始类的代码。
class Counter {
public:
int getValue() const { return value_; }
void setValue(int value) { value_ = value; }
private:
int value_ = 0;
};
class CounterAdapter {
public:
CounterAdapter(Counter& counter) : counter_(counter) {}
int getValue() const { return counter_.getValue(); }
void increment() { counter_.setValue(counter_.getValue() + 1); }
private:
Counter& counter_;
};
Counter counter;
CounterAdapter adapter(counter);
std::cout << "Value: " << adapter.getValue() << std::endl; // 使用CounterAdapter适配器
adapter.increment();
std::cout << "Value after increment: " << adapter.getValue() << std::endl;
- 实现装饰器模式:函数对象可以用作装饰器,在不修改原始类代码的情况下,为类添加新的功能。这使得你可以将通用的操作封装在一个函数对象中,并将其应用于多个类。
class Logger {
public:
void log(const std::string& message) const {
std::cout << "Log: " << message << std::endl;
}
};
class LoggingDecorator {
public:
LoggingDecorator(std::ostream& os, const std::string& prefix) : os_(os), prefix_(prefix) {}
template
void log(const T& message) const {
os_ << prefix_ << message << std::endl;
}
private:
std::ostream& os_;
std::string prefix_;
};
std::cout << "Before logging" << std::endl;
LoggingDecorator logger(std::cout, "Info: ");
logger.log("Hello, World!"); // 使用LoggingDecorator装饰器
std::cout << "After logging" << std::endl;
总之,C++函数对象在许多场景中都非常有用,它们提供了一种灵活的方式来封装和传递行为。