使用STL的容器的时候,如果容器内的元素为自定义的struct,那么该struct必须具备拷贝构造函数和赋值操作符重载,虽然这两个函数实现起来非常简单,但如果结构内部数据元素比较多,还是要敲很多代码的。程序员一般是最讨厌重复写这么没有技术含量的代码的,一般来说,这样的结构定义都放在头文件里面。如果为这两个函数写了太多行代码,也会导致头文件太长。
下面是几个辅助宏,可以用来减少代码行数,并减少犯错的机会。
//下面是为减少代码行的辅助宏,实现拷贝构造和赋值重载 |
注:上面的辅助宏,只适应2~7个数据元素的struct。1个数据元素没必要单独实现一个struct,超过7个数据的结构……我想这样的结构作为容器元素是不是太浪费了。
下面是一个例子:
//简化之前的数据架构 |
上面一个小小的例子,就精简了7行代码,如果这样的结构比较多,会省下不少代码行。虽然我一向不崇尚为减少代码行而增加程序逻辑复杂性,也很反对为减少代码行而忽视代码的规范性和可读性。但在软件开发过程中,在不增加程序逻辑复杂性的前提下,代码行越少,代码可读性越强。某种意义上来说,代码的可读性直接影响程序的健壮性。
此外,依靠设计的方法来保证代码的质量,比依靠程序员的细致与严谨来保证代码质量更可靠。
使用宏常常可以减少重复性编码时所犯下的错误。还是举个例子,上面那个简化之前的数据结构,有一个错误。
错误是这样的,在Node的拷贝构造函数中,我把b(node.b)误写成了b(node.a)。这样的错误,很隐蔽吧?如果在一个大的软件项目中,这个错误潜藏在系统中,会很折腾人的——数据无缘无故错乱,无任何规律,代码审查很难发现错误(谁会想到错误在这个拷贝构造这儿啊)。鄙人也曾经不幸中招,后来对系统抽丝剥茧,仔细跟踪,才终于发现问题。而且当初所有参与代码审查的人居然都没有能够发现这个错误。而这个错误是非常容易犯下的,编码速度越快的人,越容易犯下这种错误。我当时用的VC助手,输入node.之后,助手自动提示了a(因为最近一次的输入是node.a),一个回车下去,错误就发生了……
而使用宏,这样的悲剧不可能发生。一组简单的辅助宏,用了好多地方了,给自己留个纪念吧。