(原创)一个和c#中Lazy<T>类似的c++ Lazy<T>类的实现
2013-10-25 22:36
597 查看
在.net 4.0中增加一个延迟加载类Lazy<T>,它的作用是实现按需延迟加载,也许很多人用过。一个典型的应用场景是这样的:当初始化某个对象时,该对象引用了一个大对象,需要创建,这个对象的创建时需要较长的时间,同时也需要在托管堆上分配较多的空间,这样可能会在初始化时变得很慢,尤其是UI应用时,会导致用户体验很差。其实狠多时候并不需要马上就获取大数据,只是在需要时获取,这种场景就很适合延迟加载了。先看看c#中Lazy<T>如何使用的吧:
c++中目前还没有类似的Lazy<T>延迟加载类,其实延迟加载类内部用到了lamda表达式,将函数封装到lamda表达式中去,而不是马上求值,而是在需要的时候再调用lamda表达式去求值。c++11 中有lamda表达式和function,正好做这个事情,看看c++11如何实现类似c#的Lazy<T>延迟加载类吧。
再看看测试代码:
输出结果:
这个Lazy<T>类可以接收lamda表达式和function,实现按需延迟加载。和c#的Lazy<T>用法类似。不过还没c#中Laze<T>那么强大,没有增加线程策略在里面,目前还不想做得更复杂,简单够用就行。
c++11 boost技术交流群:296561497,欢迎大家来交流技术。
class LargeObject { public int InitializedBy { get { return initBy; } } int initBy = 0; public LargeObject(int initializedBy) { initBy = initializedBy; Console.WriteLine("LargeObject was created on thread id {0}.", initBy); } public long[] Data = new long[100000000]; }
class TestLazy { Lazy<LargeObject> lazyLargeObject = null; public TestLazy() { //创建一个延迟加载对象 lazyLargeObject = new Lazy<LargeObject>(InitLargeObject); } public void ReallyLoad() { //此时真正加载 lazyLargeObject.Value; Console.WriteLine("lazy load big object"); //do something } } void Test() { TestLazy t = new TestLazy(); t.ReallyLoad(); //这时,真正延迟加载时才会打印"lazy load big object" }
c++中目前还没有类似的Lazy<T>延迟加载类,其实延迟加载类内部用到了lamda表达式,将函数封装到lamda表达式中去,而不是马上求值,而是在需要的时候再调用lamda表达式去求值。c++11 中有lamda表达式和function,正好做这个事情,看看c++11如何实现类似c#的Lazy<T>延迟加载类吧。
#include <boost/optional.hpp> template<typename T> struct Lazy { Lazy(){} template <typename Func, typename... Args> Lazy(Func& f, Args && ... args) { m_func = [&f, &args...]{return f(args...); }; } T& Value() { if (!m_value.is_initialized()) { m_value = m_func(); } return *m_value; } bool IsValueCreated() const { return m_value.is_initialized(); } private: std::function<T()> m_func; boost::optional<T> m_value; }; template<class Func, typename... Args> Lazy<typename std::result_of<Func(Args...)>::type> lazy(Func && fun, Args && ... args) { return Lazy<typename std::result_of<Func(Args...)>::type>(std::forward<Func>(fun), std::forward<Args>(args)...); }
再看看测试代码:
struct BigObject { BigObject() { cout << "lazy load big object" << endl; } }; struct MyStruct { MyStruct() { m_obj = lazy([]{return std::make_shared<BigObject>(); }); } void Load() { m_obj.Value(); } Lazy< std::shared_ptr<BigObject>> m_obj; }; int Foo(int x) { return x * 2; } void TestLazy() { //带参数的普通函数 int y = 4; auto lazyer1 = lazy(Foo, y); cout << lazyer1.Value() << endl; //不带参数的lamda Lazy<int> lazyer2 = lazy([]{return 12; }); cout << lazyer2.Value() << endl; //带参数的fucntion std::function < int(int) > f = [](int x){return x + 3; }; auto lazyer3 = lazy(f, 3); cout << lazyer3.Value() << endl; //延迟加载大对象 MyStruct t; t.Load(); }
输出结果:
8 12 6 lazy laod big object
这个Lazy<T>类可以接收lamda表达式和function,实现按需延迟加载。和c#的Lazy<T>用法类似。不过还没c#中Laze<T>那么强大,没有增加线程策略在里面,目前还不想做得更复杂,简单够用就行。
c++11 boost技术交流群:296561497,欢迎大家来交流技术。
相关文章推荐
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 select 标签的方法,不用 C# 中的反射技术
- C# 单例模式Lazy<T>实现版本
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 CheckBox 标签的方法,不用 C# 中的反射技术
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- C# Lazy<T>实现单例模式
- C#性能优化之Lazy<T> 实现延迟初始化
- 用C/C++实现一个日期类,重载运算符=,==,+,-,++,--,>,>=,<,<=等
- C#性能优化之Lazy<T> 实现延迟初始化
- C#性能优化之Lazy<T> 实现延迟初始化
- C++:模拟实现类似<time.h>的计时功能
- C#性能优化之Lazy<T> 实现延迟初始化
- 用jsp<html:file>实现一个文件上传的例子,而且有验证
- 短信猫软件的实现(C#)<十一>软件实现(完结篇)
- 粗谈C#里 dictionary,HashTable,List<T>,Array 的性能优缺和实现原理。
- <Machine Learning in Action >之二 朴素贝叶斯 C#实现文章分类
- Sys请教下如何用C#开发一个简易的电路模拟程序<qi>
- <Unity UGUI>使用c#反射实现UGUI文本显示的国际化
- 短信猫软件的实现(C#)<五>PDU格式解码C#实现
- C++ 实现的netstat -an 的功能<转>-目的为获取rtmp推流地址如果是域名的话查看1935的ip
- C++第九周【任务三】定义分数类中<<和>>运算符重载,实现分数的输入输出