您现在的位置是:首页 >技术交流 >Star_Tool: tool包下get_set依赖设置器(getter_setter退化版本,更加贴切C#的get、set调用方法)网站首页技术交流

Star_Tool: tool包下get_set依赖设置器(getter_setter退化版本,更加贴切C#的get、set调用方法)

菜鸟小田 2024-06-17 16:40:15
简介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的生命周期。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。