C++总结之基础篇

来源:互联网 发布:xy烈咬陆鲨mega数据 编辑:程序博客网 时间:2024/05/31 18:53

使用C++语言已经有好多年了,从来没有好好总结过,这里利用effective C++的结构进行了简单的总结,希望对以后的工作有所帮助。

一 C++语言常识性总结
关于常量
1.对于单纯的常量,最好以const对象或者enum定义替换#define定义。
2.对于形似函数的宏(marcos),最好改用inline函数替换#define。
关于const
1.将某些东西声明为const可帮助编译器侦测出错误用法。Const可以被施加于任何作用域内的对象,函数参数,函数返回类型,成员函数本身。
2.在使用const修饰对象时,编译器强制实施bitwise constness,我们编写程序时应该使用”概念上的常量性”。
3.当const和non-const成员函数有着实质等价的实现时,令non-const 版本调用const版本可以避免代码重复。
关于对象的初始化
1.为内置型对象进行手工初始化,因为C++并不保证初始化他们。
2.构造函数最好使用成员初值列(member initialization list),而不是在构造函数本体内使用赋值操作(assignment)。初值列列出的成员变量,其排列次序应该和他们在class中的声明次序相同(这个只是约束,其实即使你不按声明顺序排,编译器也会以声明次序初始化)。
3.为避免“跨编译单元之初始化顺序”问题,请以local static对象替换non-local static对象, Singleton是绝佳的选择。(大型应用中,这个涉及的较多)。

二 对象的构造析构和赋值
构造和析构以及赋值
1.由于编译器会在背后做很多事情,编译器会暗自为你的class创建默认构造函数,拷贝构造函数以及拷贝赋值操作符和析构函数,如果你不需要,就必须明确地向编译器表明,你不需要这些,我们可以将相应的成员函数声明为private并且不予实现。
2.带有多态性质的基类应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。
3.Classes的设计目的如果不是作为base classes使用,或者不是为了具备多态性质,就不应该声明virtual析构函数。
析构函数中的异常
1.析构函数中绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吐下它们(不传播)或者结束程序。(由于析构函数抛出异常而引发的问题,在现实的工程发生过,影响很大)。
2.如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。
3.构造或者析构中不要调用virtual函数。在构造和析构期间不要调用virtual函数,因为这类调用从不会下降至derived class。(就是在调用virtual时,当前类的构造尚未完成,调用的是该类的上层,因此调用发生的行为可能和你想象的不一样,可以参照C++对象模型相关章节)。
赋值操作符的问题
1.令赋值(assignment)操作返回一个reference to *this。
2.需要确保在对象自我赋值时operator=有良好的行为。其中的技术包括比较“来源对象”和“目标对象”的地址,精心周到的语句安排,以及copy-and-swap。
3.确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。
拷贝函数的问题
1.拷贝函数应该确保复制“对象内的所有成员变量”以及“所有base class成分“。(这点很重要,我经常忽略,而且现实的应用软件中也发生过事故)。
2.不要尝试以某个拷贝函数去实现另一个拷贝函数。应该将共同的机能放进第三个函数中,并由两个拷贝函数共同调用。

三 资源的管理
使用对象管理资源和资源管理类
1.为防止资源泄漏,请使用RAII(Resource Acquisition Is Initialization)对象,它们在构造函数中获得资源并在析构函数中释放资源。
2.两个常被使用的RAII classes分别是tr1::share_ptr和auto_ptr。前者通常是较佳选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向null。
3.复制RAII对象的时候,必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
4.普遍而常见的RAII class 拷贝行为是:抑制copying, 施行引用计数法。
5.由于APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源“的方法。
6.对原始资源的访问可能经由显式转换或者隐式转换。一般而言显式转换比较安全,但是隐式转换对客户比较方便。
New 和 delete
1.成对使用new 和 delete时要采用相同的形式。(带[]和不带[]的区别)。
2.应该以独立的语句将newed的对象置入智能指针。如果不这样,一旦异常被抛出,有可能导致难以觉察的资源泄漏。

以上是基础知识的总结,是十分有用的,虽然是一看就知道应该避免的行为,但是实际的工程开发中难免会有不希望发生的事情,所以,时时谨记,处处当心,方能防患于未然。

-- 文档结构参照《Effective C++ -- Third Edition》

-- 转载请注明出处

原创粉丝点击