525 字
3 分钟
通过 RIME 学习 C++ 系列:3
重载运算符 operator
重载运算符的本质是函数,声明如下:
返回值 operator符号(参数) {
}
如 src/rime/algo/spelling.h
中代码
struct Spelling {
string str;
SpellingProperties properties;
Spelling() = default;
Spelling(const string& _str) : str(_str) {}
bool operator==(const Spelling& other) { return str == other.str; }
bool operator<(const Spelling& other) { return str < other.str; }
};
Spelling
重载了符号 ==
与 <
,方便对 Spelling
进行比较。const
修饰参数,表示不能修改。
类型转换操作符
class Meter {
private:
double length;
public:
Meter(double len) : length(len) {}
operator double() const { return length; }
};
int main() {
Meter m(5.0);
double len = m; // Here, the type conversion operator is used.
std::cout << "Length in meters: " << len << std::endl;
return 0;
}
在本例中,operator double()
是一个类型转换操作符,允许将 Meter 类型的对象转换为 double。在执行 double len = m;
这一行时,使用 operator double()
函数将 Meter 对象 m 隐式转换为 double,并将结果存储在 len 中。
在 rime 中这种语法也很常见,如:src/rime/config/config_types.h
...
class ConfigItemRef {
public:
ConfigItemRef(ConfigData* data) : data_(data) {}
virtual ~ConfigItemRef() = default;
operator an<ConfigItem>() const { return GetItem(); }
...
这里可以将 ConfigItemRef 类型变量转为 an<ConfigItem>
类型。
Boost 中事件管理 Signal 与 Slot
在 src/rime/common.h
中有这样的代码:
using boost::signals2::connection;
using boost::signals2::signal;
using
是用来方便引用 connection
与 signal
,后续代码就可以直接使用 connection
与 signal
类型了。
了解这些后,RIME 中用它来做什么呢?
boost::signals2 是事件管理框架,类似 Swift 中的 Combine 框架。这不过这里的把相关名词换成了 Signal
与 Slot
Signal
相当于事件,Slot
相当于事件的订阅者。
void slotTest1(int a) {
std::cout << "call slotTest1: " << a << std::endl;
}
void slotTest2(int a) {
std::cout << "call slotTest2: " << a << std::endl;
}
struct HellWorld {
void operator()(int a) const {
std::cout << "HelloWorld: " << a << std::endl;
}
};
int main(int argc, const char * argv[]) {
boost::signals2::signal<void (int)> sig;
sig.connect(slotTest1);
sig.connect(slotTest2);
HellWorld hello;
sig.connect(hello);
sig(100);
return 0;
}
当然 slot 也可以回传值,当多个 slot 时,使用最后一个 slot 的值作为返回值。
在 RIME 中,用它来完成 Context 中的各种事件通知。
src/rime/context.h
:
class RIME_API Context {
public:
using Notifier = signal<void(Context* ctx)>;
using OptionUpdateNotifier = signal<void(Context* ctx, const string& option)>;
using PropertyUpdateNotifier =
signal<void(Context* ctx, const string& property)>;
using KeyEventNotifier =
signal<void(Context* ctx, const KeyEvent& key_event)>;
...
通过 RIME 学习 C++ 系列:3
https://fuwari.vercel.app/posts/rime/rime_learn_03/