C++ Idioms: Pimpl

C++的Pimpl惯用法或者说Pimpl模式,又被称为编译防火墙,是一种在头文件中隐藏实现的方式。Pimpl很古老,可能在标准C++诞生之前就有了这种用法,其间争论也早已尘埃落定,用和不用各有利弊,主要还是看组织内部的规范和项目的需要。最近Team一直同时在两个subsystem下工作,两个subsystem的code base一个用了Pimpl一个没有用,是以在Team中产生了到底要不要用的争论。虽然SA的决定是维持现状,但还是总结下Pimpl的相关知识,以备参考。

Pimpl 没有固定的形式,有的很复杂,如Qt中的private class和D-Pointer的结构。而Team在项目中用到的相对很简单,只是一个智能指针加一个Inner Class, 基本结构如下。

Read More

C++ Idioms: Erase-Remove

STL标准库中remove算法是比较容易被人误用的算法。std::remove的行为并不像的它名字的字面意思一样,删除容器中的某些元素,而是将容器中不被删除的元素依次向前移动。或许只有中国的程序员会对这个算法有误解,毕竟英语中remove还有”移动”的含义,只是中文经常翻译成删除。

Read More

vim中的杀手级插件: YouCompleteMe

Vim代码补全现状

在漫长的Vim发展历史中,代码补全一直是比较被忽视的环节,相比众多IDE,vim本身的代码提示功能包括其众多补全插件显得无比简陋, 这是因为vim的先天不足,它是文本编译器,不能理解程序语意。引用王垠的一段文字:

“文本编辑器”这种东西一般都不真正的理解程序语言。很多 Emacs 和 vi 的用户以为用 etags 和 ctags 这样的工具就能让他们“跳转到定义”,然而这些 tags 工具其实只是对程序的“文本”做一些愚蠢的正则表达式匹配。它们根本没有对程序进行 parse,所以其实只是在进行一些“瞎猜”。简单的函数定义它们也许能猜对位置,但是对于有重名的定义,或者局部变量的时候,它们就力不从心了。


或许对于python,PHP等动态语言,因为本身的语言特性和丰富的工具支持,也能做到不错的补全效果,但对于C/C++代码的补全, AutoComplPop, omnicppcomplete, neocomplcache等插件的确都是在”瞎猜”。

Read More

C++ Idioms: CRTP

CRTP是奇异递归模板模式(Curiously Recurring Template Pattern)的缩写,是Jim Coplien在1995年提出的C++惯用法。尽管已经接近20年过去了,当使用boost, WTL等C++库的时候,依然能经常见到它的应用。

CRTP的基本形式:

1
class T : public X<T> {…};

通过在父类中传入子类的类型,实现在编译期的多态(静态多态)。当然编译期的多态比运行时通过虚函数实现的多态(动态多态)效率要高,但是这并不是CRTP模式最重要的优点。既然名字叫”奇异”,当然有奇异之处。看下面著名的类计数器代码:

Read More

在Phabricator中创建Code Review任务

Phabricator集成了众多有用的软件开发的工具,现在为止只在Team中试验了用Differential做code review和用Diffusion查看代码。Phabricator提供了一个CLI工具Arcanist, 可以用命令行操作大多数phabricator功能。Phabricator推荐用户使用Arcanist创建和管理revision (在Differential中,每一个code review任务被称作一个revision),当然用户可以完全可以使用web客户端,手动创建revision。

下面简要介绍下两种操作方式,所有操作都是在linux下,以svn为例。

Read More

Vim中的杀手级插件:VimIM

###一生的Vim路,为了一个可以用的编辑器
看到过一篇文章叫《Just Use Sublime Text》, 有人翻译成了中文。作者用Vim写文章,痛陈Vim十大罪状,劝别人不要用Vim。真是典型的Vim症候群啊,恨它却又离不开了。

作为一个Vim”深毒”用户,在开始用octopress写博客时,自然没有考虑过其他可能性,vim编写markdown也无比犀利。但是有一个问题却突然尖锐起来,vim的世界是基于英语的,支持utf8都没几年。虽然可以输入中文,但是在模式切换间,一切都混乱了,不停的在输入法的快捷键和ESC间倒腾,完全不是vim的风采。Vim的伟大之处就是给了技术宅无限的折腾空间,让他们在不停的自虐中,在承受痛苦和获得满足间不断循环。 于是Vimim诞生了,一个vim-script实现的VIM内置输入法。

Read More

开始学习Git

做为程序开发者,你一定绕不开的就是版本控制系统VCS (或者代码管理系统SCM),它并不仅仅是一个工具那么简单,更代表的是一种软件从开发调试到发布过程的组织哲学,不仅是工具命令更是方法论。

使用svn的经验

做软件开发很多年,但对于版本控制很长时间只用过subversion, 很久以前在windows上用TortoiseSVN, 后来转到linux下用命令行,用rabbitvcs, 在svn的圈圈内从来也没有出来过,一切都理所当然,从来也没有觉得svn有什么不好。直到Team要和在Stockholm的团队一起开发,checkout一个branch要一晚上,update前一天欧洲团队的commits要十几分钟,同步代码变成了一个很浪费时间的事,Team开始时把主要的开发branch, checkout到本地办公室的服务器,开发人员需要某个branch的时候,先拷贝到本机,做switch或update后开始工作。后来在本地建了个svn镜像,耗时的操作可以通过镜像做,再后来公司升级了网络,更改了svn部署策略,同步代码虽然依然很耗时,但是已经不再不可忍受。但是如果要做bug fixing, 定位bug, 理解bug引入的上下文,需要查看svn历史记录,简直就是不可完成的任务。查询svn log, 对比两个版本间某个文件的修改,都需要和欧洲的服务器通讯,而且定位一个bug, 往往需要多次的查log看diff, 耗费了大量时间,思路也常常被打断。为了这个,我还写了个工具,叫svn history, 有一个方便查看svn repos的GUI, 查svn log时会自动从本地svn镜像读取,提供针对commit的author, reviewer, filename, log message等信息的查询功能,用户将commits缩小范围后,可以很方便查看每次相关commit的修改内容,从而让开发者能够快速理解代码的演变,定位bug的位置。这个工具还很不成熟,但是在日常开发过程中,却帮了我很多忙。正是在写这个工具的时候,为了把代码上传到Github上,我才接触了Git, 了解到了svn以外的世界,在用Pages发布博客后,对Git的使用越来越频繁,发觉是时候深入的学习下Git了。

Read More

vim中的杀手级插件: surround

大多数编程语言的语法都用到了配对符号surrounding: (), [], {}, <>, ‘’, “”,标记语言xml html 等更是完全依赖与这种语法。正常输入时,所有的编辑器都能胜任,大部分会在你输入一个括号时帮你补全另一半。vim 也有这样的插件auto-pair, 但是这个不是重点,真正的难题是当你需要为已一些存在的代码加上括号,删除一对括号但保留其中的内容,或者把一对()改成[],又或者把<div></div>改成<p></p>

Read More