C++中的bind、function以及lambda表达式
在C++98中就有了函数对象(function object),为了方便从二元函数得到一元函数,引入了bind1st和bind2nd,这种场景在C++ STL中应用的很常见。随后C++11从boost库中引入了功能更强大的bind (以替代bind1st和bind2nd) 以及function函数对象机制。由于函数对象仍然需要额外定义,且有时很不方便,所以又引入了lambda表达式。 本文逐一介绍这些概念,以及背后的实现原理。 …
在C++98中就有了函数对象(function object),为了方便从二元函数得到一元函数,引入了bind1st和bind2nd,这种场景在C++ STL中应用的很常见。随后C++11从boost库中引入了功能更强大的bind (以替代bind1st和bind2nd) 以及function函数对象机制。由于函数对象仍然需要额外定义,且有时很不方便,所以又引入了lambda表达式。 本文逐一介绍这些概念,以及背后的实现原理。 …
C++中堆上的动态资源管理是一个容易出错的地方,借助RAII(Resource Acquisition Is Initialization,资源获取即初始化),能够简化资源管理,依此思想产生的智能指针极大的简化了编程。 本文先简要介绍C++中资源管理,然后介绍RAII,最后在这些概念上实现一个简单的不带引用计数的智能指针和带引用计数的智能指针,以加深对这些知识的理解。 C++中的栈、堆及资源管理 与C#中的概念相似,在C#中,值类型的对象大多数情况下是在栈上分配的,而引用类型的对象,则默认在堆上分配,这些都是默认行为,不需要手动指定,栈上的内存在出作用域后会被回收,而堆上的内存,则由垃圾回收器负责回收。 在C++中则复杂的多,它有三块内存区域: 静态内存,用来保存局部static对象、类的static数据成员,以及任何定义在函数之外的变量,分配在静态内存中的对象由编译器自动创建和销毁。 …
在C++中,有个著名的The Big Three,即:如果要显示声明析构函数、拷贝构造函数和拷贝赋值操作符,那么需要显示声明所有的这三者。拷贝构造函数和析构函数实现起来比较容易,但是拷贝赋值操作符则要复杂很多。因为与拷贝构造不同,拷贝赋值需要先把当前的资源释放,然后重新构造。这与之前单例模式中的某些场景一样,有许多需要注意的问题。copy-and-swap就是完美的解决方案。它可以很好地帮助拷贝赋值操作符达到两个目标:避免代码重复、提供强烈的异常安全保证。 …
在C++中,对象默认都是值语义,比如在对象A里面定义了成员变量B和C,那么B和C会被直接放在A的内存空间里,这样做的优点是保证了内存访问的局部性,这在现代处理器架构上具有绝对的性能优势。但缺点是,在对象复制时,具有很大的开销。而在Java或者C#里面,默认存储的是引用或者说是指针。因为C++存储完整对象这个特性,而这会导致大的复制开销,所以C++需要移动语义这一优化,而在Java或者C#中则根本不需要这一概念。一句话总结就是,移动语义使得C++里返回大对象(比如容器)的函数和运算符的性能得到极大提高。 …
最近想在Window系统上安装一个包含计划任何和闹钟提醒的应用,之前这些东西一般是在手机上完成的。后来发现微软花大价钱购买了一款名为To Do的应用,并起名为了Microsoft To Do,这是一款跨平台的应用,所以比较符合我的要求。但当我访问它的网站时,点击下载发现没有任何反应。后来我才意识到它是一个Windows Store应用程序,跟之前的WinDbg一个德性,看来时需要一定的技巧才能安装的上。 …
在C++中,对象可以粗略的分为两大类,一类是基础对象,它不包含对外部堆上对象的引用,比如普通的编译器内置类型,这类对象的构造函数和析构函数系统可以默认生成且满足要求,拷贝构造函数和拷贝赋值运算符都是默认的对内存的拷贝,这些也大都满足要求。另外一大类是对象包含指针,即包含有指向堆内存对象的引用。所以在涉及到容器的时候,就有必要将对象的内存分配和构造,内存释放和析构分开来,这就是容器的空间分配器的作用,更进一步容器的空间分配器还可以对内存分配进行池化管理从而提升内存使用效率。本文就简单介绍以下为什么容器需要空间分配器,以及一个简单的空间分配器的实现。 …
有时候我们需要监控外网网络的连接状况,通常的做法是在本机ping一些网络地址,比如sina。要实现这一目的,可以编写bat脚本不间断ping目标地址,并将返回结果保存到文本文件中,也可以使用Zabbix做一些配置来不间断监控网络状况,本文介绍这两种方法的具体实现。 …
在.NET中的基础类库(Basic Class Liberary,BCL)中有一些基本的数据类型比如Stack、List、Dictionary、LinkList等等,这些类型虽然看上去五花八门,但是其内部的实现所使用的数据结构无外乎是那些经典的结构比如数组、链表、哈希表、树等。了解这些类型背后的结构就能很清楚的知道对应数据类型的插入、查找、删除的时间和空间复杂度。在应用开发中可以根据具体的使用场景,选择合适的、高效的数据结构可以提高应用程序的效率。本文试图通过源码来查看这些基本类型的内部实现方式。 …
前几天看到一篇新闻里做的下面这张股票热点图,单纯的觉得这个图很好看,于是研究了一下如何自己绘制这个图,后来发现这种类型的图还有个专有的名字,叫treemap图。本文先介绍什么是treemap图,然后展示如何使用C#来生成沪深300指数的treemap。 …
端口转发在有些时候还是比较有用的,它能够在数据传输的过程中增加一个“路由”,提供了某种程度的灵活。本文简单介绍了工作中遇到的一个可能使用端口转发能解决的例子,以及如何使用端口转发,包括介绍了在Windows上的内置的端口转发工具,以及一些开源的端口转发程序,最后再简单介绍了如何使用C#实现一个端口转发工具。 …