高效effective C++ 55条款之个人学习笔记一
条款1:C++是一个语言体系
把C++语言作为一个成熟完整的语言体系,而不是单纯的C的扩展和延伸。因为它的特性比较广泛,比如面向对象,模板,标准库,
泛型编程等等。Object- oriented C++ .Template C++ STL containers, iterators,algorithms
条款2:尽量使用const,enum,inline替换#define关键字
这样我们可以使用编译器替换预编译器。因为预编译器会在编译之前,进行了替换,没有标记,不利用进行调试跟踪。(同时我觉得
也不利用面向对象类的封装和约束)。Const 可以定义限制常量和方法,对于方法和变量会有更安全更合适的控制权限。enum 可
以定义一些类和对象所使用的整形常量。安全性,封装性也更好。 Inline内联函数,也是为了提高程序效率,以空间换取时间,替
代了函数入栈出栈的过程,使得效率进一步提升。但是注意的是,尽量使用短而小的函数定义为内联函数,一般建议十行以内
(除去递归)。比如:
{
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对象指针。只要返回对象引用=,+=
你最好都按照此标准,这样也可以实现连锁赋值。这是一种比较好的习惯和严谨的编码方式。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。