前段时间写了不少代码,不是随手写练习,而是一整个项目做下来的,于是就有了一些以前不曾有的心得,不过都来源于《有效C++》之类的书,只不过自己亲身经历之后体会更深刻一点。
1 一个类的成员变量实在太多的时候,对这些变量进行分类包装吧。我写过一个类,里面有很多数据成员,多得在编写该类的功能函数的时候常常要去头文件回顾各个变量的名称和意义。后来觉得太难受,就将这些变量分类,一个类别是关于运动变量的,一个类别是关于摄像机运动的,还有一个类别是物理规则方面的,也就是说我在该类内部声明了3个struct,并实例化了他们。
个人的感觉是,对于烦杂的东西进行适当的归类,便于管理。
2 Log类。一个项目是要时刻注意将一些运行信息进行输出的,那些信息对调试具有不可取代的意义,透明化的意义就在于此。事实上,当编写的项目涉及到第三方库的时候,很有可能依靠带断点的debug运行已经极为耗时,所以LogOut必要的信息是有益的,不要吝啬代码。
3 Exception类。如果你所依赖的库没有提供该类,那么在你的项目中自己写一个,因为一般说来,std::exception并没有提供你想要的东西。不要讨论Exception所带来的开销,这里是C++,而异常所带来的手感,胜过返回值10倍,而逻辑上也清晰得多。
4 杂七杂八的东西都放到类初始化成员列表里不是什么好事。初始化成员列表是讲究顺序性的,可是类在实现的时候成员变量是一个逐步添加的过程,东西多了,就会乱了,初始化列表里的顺序也就对不上了。
一般来说,只有那种需要拷贝构造函数初始化的变量,才放到初始化列表里。
5 成员变量的初始值赋值。成员变量很多的话,如何在它们初始化的时候传递变量呢?构造函数是初始化的最好选择。但是,一个拥有十几个参数的构造函数吗?又或者在类完成构造之后,通过set函数来设置?由此带来的接口庞大,还有修改失控问题却不能忽视。
在构造函数中传递一个文件名吧,然后该类负责从文件中读取各个成员变量的初始值。我是比较倾向于这个方式的,其实类内很多变量都是规则性变量,通过从外部流中读取,那么只要编译一次,就可以得到不同的结果了,何乐而不为呢。
6 尽量不使用protected。这里是说一个类层次设计的,作为基类,可以理解为子类的抽象,不过更多的时候,这种抽象对于我来说只是一个概念的问题,毫无意义。设计基类的真正原因,是接口通用,还有代码复用,这在我看过的某些代码里面都是如此的,抽象的意义让人觉得很困惑,但是一想到是代码复用,也就霍然开朗。
基类用public给出接口,用private给出变量,也许你会问,如果子类要用这些变量怎么办?那么好吧,先说protected后会怎么样吧。基类的成员变量的使用权遗留给了子类,可惜我并不喜欢那些基类的成员变量,为什么?因为在我的经验中,基类遗留下的变量都是相当庞大的,甚至有好几个层次的基类,那些变量,经历了一段时间之后,你还能对他们的名称和意义烂熟于心吗?我反正是糊涂的,反而在子类添加的变量最明白不过。
那么如果一定要用基类的变量怎么办?你用那个变量只不过要实现某些功能,那么把那个功能的实现做在基类的一个函数就好了,函数总比变量来的明白。
事实上,我并不能很肯定本条规则,因为有的变量真的是不把使用权遗留下去是不行的啊。不过尽量少用protected是没错的吧。
7 尽量少在一个封闭的函数内成对的进行动态内存分配和释放,这种情况往往是想要一个不定长的临时变量,如果可以,就用一个尽量长的buffer更好,否则你就要添加异常情况下删除该变量的代码。
我尽可能的只在构造函数和析构函数中应付动态内存。
8 代码越来越多,你能渐渐嗅出代码冗余的味道了,重构吧,我常常是边写边重构,而不是等所有东西都完成后才这样做,因为那样要改更多。
posted on 2006-05-31 19:59
LOGOS 阅读(1371)
评论(5) 编辑 收藏 引用