您现在的位置是:首页 >技术交流 >Star_Tool: tool包下get_set依赖设置器(getter_setter退化版本,更加贴切C#的get、set调用方法)网站首页技术交流
Star_Tool: tool包下get_set依赖设置器(getter_setter退化版本,更加贴切C#的get、set调用方法)
大纲链接:
Star_Tool:一个C++跨Windows和Linux的工具库_菜鸟小田的博客-CSDN博客
最近在学Unity 用C#时发现get、set和我之前想象中的不太一样,之前短暂接触C#只短暂地知道这一原理,可是原来的getter_setter也有一定的用武之地,它是将变量直接包装在依赖设置器内,那么在类内的赋值和取值操作也会经过依赖过滤器。本节的版本get_set将会将变量数据放在外面,而以保存引用的方式保存在get_set,并只有在外部赋值时才会走依赖过滤器。给出头文件声明代码:
template<typename DATA_TYPE>
class get_set
{
public:
get_set(DATA_TYPE& data);
get_set(DATA_TYPE& data, std::function<DATA_TYPE(DATA_TYPE)> getter, std::function<DATA_TYPE(DATA_TYPE)> setter);
get_set(const get_set<DATA_TYPE>& CopySource) = delete;
get_set(get_set<DATA_TYPE>&& MoveSource) = delete;
~get_set();
get_set<DATA_TYPE>& change_setter(std::function<DATA_TYPE(DATA_TYPE)> setter); //修改setter,流式依赖注入器
get_set<DATA_TYPE>& change_getter(std::function<DATA_TYPE(DATA_TYPE)> getter); //修改getter,流式依赖注入器
get_set& operator =(DATA_TYPE data);
operator DATA_TYPE();
DATA_TYPE move();
DATA_TYPE copy();
DATA_TYPE& ref(); //!!危险方法,在修改引用时会略过setter过滤器,这应仅仅用于调用DATA_TYPE的函数。
using type = DATA_TYPE;
private:
DATA_TYPE& data;
std::function<DATA_TYPE(DATA_TYPE)> getter;
std::function<DATA_TYPE(DATA_TYPE)> setter;
};
它保留了大部分getter_setter方法包括change_setter、change_getter、move、copy、ref等等,但数据是通过在构造时传入数据的引用实现的,这个方法的好处是将数据的初始化和依赖过滤器的初始化分离开,让使用者用它编写代码时逻辑更加清晰,而不用在构造函数中特意去调用change_setter、change_getter。
getter_setter的简介文档传送门:
https://blog.csdn.net/qq_29322325/article/details/130738120?spm=1001.2014.3001.5502
该代码与getter_setter代码不同,其原理图自然也不同:
可以发现,get_set的原理图和getter_setter只在最后过滤数据后交付的对象不同,getter_setter是将数据交付回到getter_setter,而get_set是交付到数据的引用处。
因此,在这个结构初始化时必须明确指向的引用,所以我删除了大部分构造函数,只保留了部分需要传入数值引用的构造函数.
因为将数据本体和过滤器分离,数据的生命周期必须大于或者等于过滤器的生命周期,这只能由调用的程序员自己实现,不过不建议在函数内对象使用,一般当作类内变量对象使用。
getter_setter(DATA_TYPE& data);
传入数据本体的引用,其依赖过滤器将会采用默认的依赖过滤器。
getter_setter(DATA_TYPE& data,
std::function<DATA_TYPE(DATA_TYPE)> getter,
std::function<DATA_TYPE(DATA_TYPE)> setter);
构造函数,可以自定义依赖设置器和依赖获取器,完成对依赖数据获取和设置的过滤操作。其data传入数据本体的引用
~getter_setter();
默认析构函数,无功能。
getter_setter<DATA_TYPE>& change_setter
(std::function<DATA_TYPE(DATA_TYPE)> setter);
修改依赖注入器setter,需要满足流式依赖注入器。
getter_setter<DATA_TYPE>& change_getter
(std::function<DATA_TYPE(DATA_TYPE)> getter);
修改依赖获取器getter,需要满足流式依赖注入器
getter_setter& operator =(DATA_TYPE data);
重载了代理的赋值符号,会将data数据走一遍依赖注入器后才把数据注入该容器。
operator DATA_TYPE();
重载了代理的隐式转化,会将data数据走一遍依赖获取器后才把数据返回给调用者。
DATA_TYPE move();
会将容器内数据以std::move的方式走一遍依赖获取器才把数据返回给调用者。
DATA_TYPE copy();
会将容器内数据以copy拷贝的方式走一遍依赖获取器才把数据返回给调用者。
DATA_TYPE& ref();
!!危险方法,会直接返回数据的引用,在修改引用时会略过setter过滤器,这应仅仅用于调用DATA_TYPE的函数。
using type = DATA_TYPE;
类内数据类型的静态存储。可以静态获取其内部的数据类型。
最后附上使用案例代码:
class MyClass
{
public:
MyClass() :buf { 0 }
{}
~MyClass() = default;
star::get_set<int> Buf{
//data:
this->buf,
//getter:
[](int i) {
return i;
},
//setter:
[](int i) {
return i > 99 ? 99 : i;
}
};
private:
int buf;
};
int main() {
MyClass class_cs;
cout << class_cs.Buf << endl;
class_cs.Buf = 999;
cout << class_cs.Buf << endl;
}
运行结果:
达成效果。
最后,不建议这样使用:
int main() {
int i;
star::get_set<int> I(i);
}
这需要程序员自己确认i和I的生命周期。