您的位置:首页 > 编程语言 > C语言/C++

[置顶] 高效effective C++ 55条款之个人学习笔记一

2014-12-04 10:37 561 查看
条款1:C++是一个语言体系

把C++语言作为一个成熟完整的语言体系,而不是单纯的C的扩展和延伸。因为它的特性比较广泛,比如面向对象,模板,标准库,

泛型编程等等。Object- oriented C++ .Template C++   STL containers, iterators,algorithms

条款2:尽量使用const,enum,inline替换#define关键字

这样我们可以使用编译器替换预编译器。因为预编译器会在编译之前,进行了替换,没有标记,不利用进行调试跟踪。(同时我觉得

也不利用面向对象类的封装和约束)。Const 可以定义限制常量和方法,对于方法和变量会有更安全更合适的控制权限。enum 可

以定义一些类和对象所使用的整形常量。安全性,封装性也更好。 Inline内联函数,也是为了提高程序效率,以空间换取时间,替

代了函数入栈出栈的过程,使得效率进一步提升。但是注意的是,尽量使用短而小的函数定义为内联函数,一般建议十行以内

(除去递归)。比如:

enum

 {

          MAX_PATH_SIZE=1024,

          MAX_BUFF_SIZE=1024*10,

 };

inline bool CBase64Crpyt::IsBase64( unsigned char c)

{

      return (isalnum(c) || (c == '+') || (c == '/'));

}

条款3:尽可能使用const.

为什么这样说呢,因为这个关键字会告诉编译器进行严格约束。非常适合保护那些方法和属性,不管是指针,文件,函数。比如:

static const TCHAR * const MUTEX_FLAG;

static const string base64_chars;

string Base64Decode(string const& en_string) ;

条款4:适用对象前确定已经被初始化


C++初始化对象的方法主要在构造函数中完成。有两种方式一种是构造函数内部初始化(这里说的是内置类型),一种是初始化成员列表。

Constructor ()

{

Int i=0x0;// 内置类型初始化

}

Constructor (int iIndex):m(iIndex)//初始化

//编译器会先调用默认构造函数,初始化列表,然后调用用户定义构造函数。

{

m=iIndex;//这个不叫初始化,叫赋值。

}

还有一个C++对于不同编译单元的non-local static对象的初始化次序,没有作出明确的定义。

对此采用本地函数返回一个对象的引用,即可解决此问题。

FileSystem & tfs()

{

statuc FileSystem fs;

return fs;

}


条款5:了解C++默默编写并调用的那些函数


 

Class Empty()

{

Public:

 Empty(){};//默认构造函数

Empty(const Empty&em){};//copy构造函数

~Empty(){};//析构函数

Empty& operator=(const Empty& em){};//copy assignment操作符

}

编译器可以默认不声明的情况下,给你所定义的类默认自动生成以上所有函数。

因此你的必须明白,自己什么时候需要创建自定义构造函数,copy构造函数等。

 


条款6:若不想使用编译器自动生成的函数,那么就应该明确拒绝


默认情况下,当用户自己不实现copy构造函数和copy assignment(就是=重载复制)。编译器会自己生成,当某些时候我们需要我们的

对象独一无二的时候,就必须禁止对其进行复制。那么最好的办法就是把这些函数定义出来,属性为private函数,并且不去实现它。

这样就可以安全的保护我们的对象。

条款7:为多态基类声明virtual析构函数

 
C++明确指出,当derived class对象经由一个base指针被删除,而该base class 带着一个non-Virtual析构函数,其结果是未定义的。

实际执行的时候是对象的derived成分没有被销毁。既然是未定义的,那么就是未知,危险的。所以记住在有多态性的基类应该给析

构函数声明称virtual,同理相反而言,如果本身不具有多态情况,那么则不要声明为virtual析构函数。



条款8:别让异常逃离析构函数


这句话呢,就是说如果你在析构函数里面编写了异常处理,那么你必须记得不能让它逃出去。也就是必须让它在析构函数内部自己对

异常扑捉,处理。失败了也不能让异常扩散,跳出析构函数。另外如果客户要求对异常的抛出做出反应,那么建议提供接口函数,

供其捕捉,调用处理。

 
条款9:绝不在构造和析构过程中调用virtual函数

该条款若不遵守,也将会带来很大危险。同样你是java或者c#程序员,就更加得注意这个问题了。比如你在一个基类的构造函数调用了虚函数,

同时定义了一个子类,那么子类必然会先调用基类的构造函数进行构造。然后在构造的时候最后调用的是虚函数,此时基类并未完全初始化对象,

就去调用多态虚函数,那么结果是很危险的。而且编译器会把其解析到基类虚函数。同理,在析构函数也不要调用。因为这类的虚函数调用,

从不会下降至子类。

条款10:令operator=返回一个reference *this

这个操作符大家不陌生吧,当你需要使用=号进行对象赋值的时候,那么你的让函数返回一个指向对象的this对象指针。只要返回对象引用=,+=

你最好都按照此标准,这样也可以实现连锁赋值。这是一种比较好的习惯和严谨的编码方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: