Cpp 语言中用什么回调方法最佳
Posted on Sun 07 January 2024 in Journal
Abstract | Cpp 语言中用什么回调方法最佳 |
---|---|
Authors | Walter Fan |
Category | learning note |
Status | v1.0 |
Updated | 2024-01-07 |
License | CC-BY-NC-ND 4.0 |
C/C++ 语言中用什么回调方法最佳
在 C++ 中,最为熟悉的回调方法莫过于观察者模式
#include <iostream>
#include <vector>
// Observer interface
class Observer {
public:
virtual void update(int value) = 0;
};
// Concrete Observer
class ConcreteObserver : public Observer {
public:
void update(int value) override {
std::cout << "ConcreteObserver received update with value: " << value << std::endl;
}
};
// Subject interface
class Subject {
public:
virtual void addObserver(Observer* observer) = 0;
virtual void removeObserver(Observer* observer) = 0;
virtual void notifyObservers(int value) = 0;
};
// Concrete Subject
class ConcreteSubject : public Subject {
private:
std::vector<Observer*> observers;
public:
void addObserver(Observer* observer) override {
observers.push_back(observer);
}
void removeObserver(Observer* observer) override {
auto it = std::remove(observers.begin(), observers.end(), observer);
observers.erase(it, observers.end());
}
void notifyObservers(int value) override {
for (Observer* observer : observers) {
observer->update(value);
}
}
};
int main() {
// Create ConcreteSubject and ConcreteObserver instances
ConcreteSubject subject;
ConcreteObserver observer1;
ConcreteObserver observer2;
// Add observers to the subject
subject.addObserver(&observer1);
subject.addObserver(&observer2);
// Notify observers of a state change
subject.notifyObservers(42);
// Remove one observer
subject.removeObserver(&observer1);
// Notify remaining observer of another state change
subject.notifyObservers(99);
return 0;
}
在实际的编程实践中,这样做挺啰嗦,自从 C++ 有了 std::bind, std::function 以及 lambda, 代码可以更简单
#include <iostream>
#include <functional>
class MyClass {
public:
// Member function that will be used as a callback
void memberFunctionCallback(int value) {
std::cout << "Member Function Callback invoked with value: " << value << std::endl;
}
};
int main() {
// Create an instance of the class
MyClass myInstance;
// Define a std::function for the callback using std::bind
std::function<void(int)> memberFunctionCallback = std::bind(&MyClass::memberFunctionCallback, &myInstance, std::placeholders::_1);
// Use the registered member function callback
memberFunctionCallback(42);
return 0;
}
又如
#include <iostream>
#include <functional>
class CallbackHandler {
public:
void memberFunctionCallback(int value) {
std::cout << "CallbackHandler's member function invoked with value: " << value << std::endl;
}
};
class AnotherClass {
public:
// Function that takes a lambda as a callback
void registerAndInvokeCallback(std::function<void(int)> callback) {
// Some other logic...
// Invoke the callback with a value
callback(42);
}
};
int main() {
CallbackHandler callbackHandler;
// Register a member function as a lambda
auto memberFunctionLambda = [&callbackHandler](int value) {
callbackHandler.memberFunctionCallback(value);
};
AnotherClass anotherClass;
// Use the lambda as a callback in another class
anotherClass.registerAndInvokeCallback(memberFunctionLambda);
return 0;
}
在 C 语言中基于 signal 信号的回调也挺好用的, 例如:
#include <glib.h>
// Define a custom object type
#define MY_TYPE_OBJECT (my_object_get_type())
G_DECLARE_FINAL_TYPE(MyObject, my_object, MY, OBJECT, GObject)
struct _MyObject {
GObject parent_instance;
};
G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT)
// Define a signal for the custom object
enum {
SIGNAL_MY_SIGNAL,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
// Callback function for the signal
static void my_signal_callback(MyObject* obj, int value, gpointer user_data) {
g_print("Signal received with value: %d\n", value);
}
// Function to perform the operation and emit the signal
static void perform_operation(MyObject* obj, int value) {
// Perform some operation...
// Emit the signal
g_signal_emit(obj, signals[SIGNAL_MY_SIGNAL], 0, value);
}
// Class initialization function
static void my_object_class_init(MyObjectClass* klass) {
signals[SIGNAL_MY_SIGNAL] = g_signal_new("my-signal",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE,
1,
G_TYPE_INT);
}
// Object initialization function
static void my_object_init(MyObject* obj) {
// Initialization code here...
}
int main() {
// Initialize GLib
g_type_init();
// Create an instance of MyObject
MyObject* obj = g_object_new(MY_TYPE_OBJECT, NULL);
// Connect the signal to the callback function
g_signal_connect(obj, "my-signal", G_CALLBACK(my_signal_callback), NULL);
// Perform the operation, which will trigger the signal
perform_operation(obj, 42);
// Clean up
g_object_unref(obj);
return 0;
}
notes
横在我们面前许多事都使人痛苦,可是却不用悲观。骤然而来的风雨,说不定会把许多人的高尚理想,卷扫摧残,弄得无踪无迹。然而一个人对于人类前途的热忱,和工作的虔敬态度,是应当永远存在,且必然能给后来者以极大鼓励的 -- 沈从文
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。