引入
作为一个喜欢偷懒的码农, 在开发C++的过程中经常遇到类属性的明明问题头疼 >_<
既然是属性, 那常用的接口无非就是设置属性, 获取属性, 监听属性变化以及限定属性的合法值范围
平常开发的时候, 基本都是一股脑的按流程走, 如:
- 定义私有成员变量
- 定义属性get方法
- 定义属性set方法
- 在set方法里里面去检验新值是否合法, 以及是否有变化等
那能不能针对这些逻辑做一些通用的api封装呢?
比如, 设置属性的时候, XXX.yyy = value
获取属性的时候 value = XXX.yyy
在设置属性的时候自动根据我们的预设检验去判定合法性,以及预设的变更回调去知道值发生了变化
原理
某个属性类型为 Type
那设置属性就会调用成员函数: operator=(const Type&)
获取属性到对应的Type类型变量时, 调用了 operator Type()
在有些需要校验合法性的属性上增加一个校验回调, 比如 willSet( [] (const Type& ) { return … ? true: false; }) 回调返回true表示校验通过, 反之则不通过, 忽略需要设置的值
在有些需要监听变化的属性上增加一个变更回调, 比如 didSet( [] (const Type& current, const Type& old) {} )
在回调中去处理属性变化的后续操作
实践
#include <oyoung/property.hpp>
#include <iostream>
#include <string>
class Student {
public:
oyoung::property<int> number{100};
oyoung::property<int> age {};
Student() {
number.willSet([=](int val) {
return val > 0; /// exclude all numbers less than 0
});
number.didSet([=](int current, int old) {
std::cout << "number changed: (" << old << " -> " << current << ")" << std::endl;
});
age.bind(_age, [=](int val) { return val > 6; } );
}
private:
int _age {6};
};
int main(int , char**)
{
Student Jack;
Jack.age = 12;
Jack.number = 1001;
Jack.number = 0; // will be ignored
std::cout << "number: " << Jack.number << std::endl;
return 0;
}
输出结果:
number changed: (100 -> 1001)
number: 1001