随笔分类 -  [3] 语言与算法

摘要:最近的一个项目,是开发一个framework,提供给公司内部不同的产品线使用。 之间遇到的一个问题,就是STL容器的使用, 而结论是不要在公共接口中传递STL容器:这里说的STL容器,但主要则是指容器,字符串类,但其实可以推广到在STL中提供的任何类型,这里说的公共接口,是指需要暴露给客户的sdk头文件,包括函数签名,或者类成员变量;也可以说,不要在暴露给客户的头文件中包含STL的头文件。原因分析为什么有这个结论,我们可以从几个方面来论述:客户端使用的STL版本可能不同因为STL作为标准库,Framework编译的时候使用的STL,与客户端编译的时候使用的STL,版本是有可能不一样的,比如Fr 阅读全文
posted @ 2011-07-10 19:32 lzprgmr 阅读(5137) 评论(12) 推荐(1) 编辑
摘要:前段时间遇到了一些与BFS有关的有趣的问题,在一些朋友或者资料的帮助下有所思考,发现这个简单的算法如果能应用自如,的确能发挥强大的功效,于是乎写篇博客记录一下。BFS概念很简单,此处有介绍;BFS实现也很简单,用一个queue就可以了;而它确实也是图中一个非常重要的算法,而它确实也可以用来解决一些看似与图没啥明显关系的问题。 理解广度优先搜索,关键在于理解其应用。1. 基本应用广度优先搜索算法是基于图定义的,所以最直观的应用自然就在图中:有明确的vertex和edge。 比如地图,某个地点就是vertex,而连接两个地点的路径,就是edge,假设edge长度都一样(当然,事实上这是不可能的), 阅读全文
posted @ 2011-04-17 21:29 lzprgmr 阅读(15403) 评论(4) 推荐(5) 编辑
摘要:之前写过一篇使用COM组件的3种方法的文章:启动COM组件的三种机制,其中后来补充了一个用免注册的方式使用进程外COM组件的方法,因为只是文字补充,没有实例,可能对于怎么实现大家不是很清楚,陆续收到一些同学的信,希望能给个例子。 所以干脆补充一篇,自己也恰好复习一下。步骤大概是这样的:我有一个com.exe的进程外com组件,暴露出一个ITestObject的接口。现在CustomizedWay.exe要调用这个com组件,但不希望通过注册表那一套。 虽然微软提供了registry-free的com组件机制,但目前只支持进程内COM组件(具体参考前文),但由于我们知道一个COM组件被调用的来龙 阅读全文
posted @ 2011-03-23 19:42 lzprgmr 阅读(9552) 评论(5) 推荐(0) 编辑
摘要:有这么个问题:我们知道C++中有虚函数的类会有一个对应的虚函数表,那么纯虚类有虚表吗,如果有的话怎么调用纯虚函数?直觉上来讲,应该是有的。 可是既然是纯虚类,说明其对象永远不会被创建,那么维护个虚表貌似也不是很必要了。可以设计个程序来验证一下:class VirtualBase{public: VirtualBase() { // call pure virtual function through a non virtual function in base class's constructor non_virtual_fun(); } void non_virtual_fun() 阅读全文
posted @ 2011-03-07 21:56 lzprgmr 阅读(3326) 评论(7) 推荐(0) 编辑
摘要:当实现一个算法或者写一个工具类的时候,我们总是需要写一些测试代码,但如果全部写在main函数里,难免组织混乱,不易清查;如果选用cppunit或者gtest等强大的单元测试框架,又是杀鸡用牛刀 - 太重了,不方便。另外一个可选的是TUT, Template Unit Test Framework,与前两者不同是其采用C++模板函数实现,而不是宏,虽说号称短小精悍,拿来一试也觉得颇显富态。其实我只需要一个很简单的框架,只是针对一个算法实现,或者一个工具类写测试,而不是项目级别的。比如我写了一个max函数求两个数中较大的那个,那么测试代码可以这么写:然后RUN_ALL_CASES就可以了。仔细想了 阅读全文
posted @ 2011-01-08 10:46 lzprgmr 阅读(2837) 评论(2) 推荐(3) 编辑
摘要:这是今天下班前和同事讨论的问题。MFC的消息映射通过几个简单的宏,对Windows的消息机制做了非常好的面向对象封装,一时为无数C++程序员所模仿(当然,MFC可能也是模仿别人的)。熟悉MFC消息映射机制的人都知道,其本质无非就是把消息和其处理函数放到一个数组当中,当程序接收到某消息时,就会遍历该数组,查找对应的消息ID,找到了就调用其处理函数,找不到就往其基类的数组当中去找。对,是线性查找!那么为什么MFC没有将消息数组排序,然后用二分查找,把复杂度从O(n)提高到O(lg n)呢?原因我想可能是没有必要,可以想像,一个类中的消息处理函数的个数是十分有限的,假设有100个消息,最坏情况也就是 阅读全文
posted @ 2010-12-10 21:25 lzprgmr 阅读(774) 评论(0) 推荐(0) 编辑
摘要:一个函数caller会在其内部调用另外一个函数callee,现在的情况是,caller可能会在多个地方被多次调用,而你希望callee只在第一次被调用时被调用一次。一般情况下,callee会是一个对环境或者资源的初始化工作。或许,从代码结构的角度来讲,你第一个想到的是把callee从caller中拿出来,放到某个合适的地方做初始化,这是个不错的方法,但相信我,在有些时候这并不是个有效的办法:你可能... 阅读全文
posted @ 2010-11-13 21:40 lzprgmr 阅读(17482) 评论(16) 推荐(4) 编辑
摘要:在VC++ 2008下编译如下代码:[代码]你会发现这段代码可以成功的编译并且运行,但是如果你足够细心,应该会发现EnumType并没有被定义,为什么使用没有定义的类型却能正常编译甚至运行呢? 原因有二:1. 函数中的参数声明enum EnumType type,不但被解析为一个参数声明,也被解析为对EnumType的一个前置声明。其实不光对enum,对class也是一样,比如[代码]也是没有问题... 阅读全文
posted @ 2010-10-16 15:03 lzprgmr 阅读(5623) 评论(5) 推荐(2) 编辑
摘要:从内存管理方面来讲,C#是个完美的天堂,你不用像在C++中那样万分小心的管理着你的内存;尽管如此,本人还是喜欢C++要多些,正如微软称C++为native代码 - C++对我来讲,的确是要更native一些。其实,很多时候,C++之于C#,就像手动挡之于自动挡。闲话不扯,一般情况下,我们会碰到的内存问题有使用未初始化的指针,使用空指针,释放已经释放过的内存等等。最近工作中也遇到两个内存相关的问题,... 阅读全文
posted @ 2010-09-02 22:23 lzprgmr 阅读(2742) 评论(9) 推荐(3) 编辑
摘要:使用gtest、或者cppunit之类的框架编写单元测试代码,一个最常见的问题是对类私有成员的测试与验证。理想情况下,我们希望在测试中,类中所有的数据与方法都是可以访问的;而在产品代码中,只暴露实现定义好的接口。gtest官方文档中,也提到了对私有成员的处理,方法不外乎两种:一是使用friend关键字,骗取信任得以通行;二是重构采用Pimpl模式,公共类中只暴露接口,而实现类中暴露所有细节(pub... 阅读全文
posted @ 2010-06-28 16:43 lzprgmr 阅读(11201) 评论(11) 推荐(2) 编辑
摘要:第一次接触Perl,还是2008年10月份的时候,当时因为项目重构,需要进行大量的文本操作,于是便拾起了以“文本操作为己任”的Perl语言。当然,带我入门的还是那本赫赫有名的The Llama Book, 即<Learning Perl> 第四版。 然而,由于主要是为了使用,所以只是快餐式的学习,并没有系统的去了解Perl,这几年来三三两两的也写了不少Perl脚... 阅读全文
posted @ 2010-05-16 09:59 lzprgmr 阅读(3443) 评论(2) 推荐(4) 编辑
摘要:这是在上周review代码时注意到的三点,感觉有些意思,不妨记录下来。如无必要,勿增虚函数比如我们有以下关于球的类层次设计 ,其中需要判断某种球是否是可以踢的(kickable):乍一看觉得挺合理的,但仔细想想,其实IsKickable是某种球的本质静态属性,用一个虚函数来表示这种信息,是一种浪费,更加合理的方式应该是用一个数据成员和一个普通成员函数:类似这样的设计我碰到过至少两次,一次是被rev... 阅读全文
posted @ 2010-04-25 10:36 lzprgmr 阅读(855) 评论(0) 推荐(0) 编辑
摘要:前几天我们项目刚刚解决了一个pure virtual function call引起的stopship的bug,乘热打铁,学习总结一下。理论上的case当一个纯虚函数被调用到时,vc++的debug模式下会弹出这么一个对话框:然后就是crash了。在网上找了一下,发现已经有人对此作了详细的介绍:"Pure Virtual Function Called": An Explanation. 这是一篇... 阅读全文
posted @ 2010-03-07 18:50 lzprgmr 阅读(2036) 评论(0) 推荐(1) 编辑
摘要:VBA支持一直是我们发布的组件的内建功能,目的有两个:一是支持内部自动化测试,二是提供给用户宏扩展的能力。但由于我们提供的是一个组件,而用我们这个组件的软件不一定需要VBA的功能,事实上,由于VBA的日渐没落(微软早就停止升级VBA了,这就是为什么VBA没有64位版本的原因,也预示着VBA的必将最终消亡),大家基本都不想要了。然而,在我们库中,VBA并不是一个可选的组件,你用也好,不用也罢,VBA... 阅读全文
posted @ 2010-02-25 16:59 lzprgmr 阅读(1768) 评论(0) 推荐(0) 编辑
摘要:前段时间做了个raytracing的程序,过程是从两个文件分别读入所有的ray和triangle,通过计算把所有的交点输出到一个文件。这里不打算讨论计算过程中算法的优化,主要是谈谈关于文件操作的一些想法。一开始用的是C++标准库提供的ifstream和ofstream, 读写操作类似于:结果发现这样的文件读写相当慢,比如说,在我双核2.16GHz,7200rpm的机子上,写2M的数据花了将近1s。... 阅读全文
posted @ 2010-01-24 21:29 lzprgmr 阅读(2052) 评论(1) 推荐(0) 编辑
摘要:C++代码一直以其运行时的高性能高调面对世人, 但是说起编译速度,却只有低调的份了。比如我现在工作的源代码,哪怕使用Incredibuild调动近百台机子,一个完整的build也需要四个小时,恐怖!!!虽然平时开发一般不需要在本地做完整的build,但编译几个相关的工程就够你等上好一段时间的了(老外管这个叫monkey around,相当形象)。想想若干年在一台单核2.8GHZ上工作时的场景 - ... 阅读全文
posted @ 2010-01-17 16:30 lzprgmr 阅读(8063) 评论(6) 推荐(2) 编辑
摘要:做当前这个项目也快一年半了,回头看看,前一年时间是在做重构,而后一年时间则是在打造一个新的产品。这里稍微总结一下做重构时所学到的一些东西吧。重构其实可以是不同目标的,有些人重构是为了让代码更合理,美观;而另一些人则可能是为了实现某个功能;重构也是有不同程度的,有的可能只是在函数、类级别做些修改,而有些则是要对整个的架构,模块做变动;同时重构的投入也是有很大不同的,有的只是在遇到不好的代码或设计的时... 阅读全文
posted @ 2009-12-27 21:26 lzprgmr 阅读(5376) 评论(0) 推荐(0) 编辑
摘要:我们知道,在Windows下是不区分大小写的,比如文件名,文件夹名,命令行参数以及注册表表项等等。这在提供我们方便的同时也把我们培养的不那么严谨,出错也就在所难免。 这是最近发生在我们公司的两个真实的案例。 1. Bin目录和bin目录 软件所有的DLL都是在Bin目录下的,有同事在fix一个defect的时候,需要判断某个DLL是否在这个Bin目录下,遗憾的是,这个判断他是用case se... 阅读全文
posted @ 2009-12-13 22:11 lzprgmr 阅读(718) 评论(0) 推荐(0) 编辑
摘要:如果你是一个程序员,而且恰好对写写代码有那么丁点兴趣的话,恐怕你会有一些属于自己的代码,这可以是你学习过程中的练习,解决问题的工具,或者纯粹就是发自兴趣的研究~~~而且你也希望有个比较好的方法来管理他们。同学毕业后一直在兼职做网站,卖空间域名,前几天在他服务器上"kiang"来了一个SVN的repository过来,很是开心 - 自己的代码终于也走上了"一处保存,多出访问"的道路。其实之前也在网上... 阅读全文
posted @ 2009-12-06 16:15 lzprgmr 阅读(578) 评论(1) 推荐(0) 编辑
摘要:如果你是C++程序员,我想你可能遇到过这样的情况:在debug时,对着一个函数step into,明明调用的是A函数,可是结果却跳进了B函数。为什么,call stack里显示的也是明明白白,就是直接进了B函数。百思不得其解,于是你怀疑是不是系统出了问题,是不是编译器出了问题,是不是调试器出了问题~~~其实那些玩意不是那么容易出错的,先看看你你的A,B函数是不是同一个类的虚函数,如果是,这极有可能... 阅读全文
posted @ 2009-11-28 09:57 lzprgmr 阅读(631) 评论(0) 推荐(0) 编辑

黄将军

点击右上角即可分享
微信分享提示