首页 > 代码库 > Effective C++ 笔记

Effective C++ 笔记

自己习惯C++
1、C++为一个语言联邦
STL,Template,智能指针,C++11

2、尽量以const,enum,inline替换#define
1)预处理在符号表中不存在,出现bug不好定位;目标码中也不会有多份Pia
eg:
#define Pia 3.14 (instead of--->) const double Pia = 3.14
2)inline代替#define函数
eg:
#define MAX(a,b) f(
if((a) > (b))
return (a)
else
return (b)
)
template<class T>
inline T Max(const T& a, const T& b)
{...}

3、尽量使用const
1)区别不多说(const出现在星号左边,表示被指物是常量;出现在右边,表示指针本身是常量;出现在两边,被指物和指针都是常量)
char str[] = "hello";
char* p = str;
const char* p = str;
char* const p = str;
const char* const p = str;
2)const std::vector<int>::iterator iter = vec.begin();//like T* const;指针不能变,被指物可以变
*iter = 10;//right
iter++;//error
遍历的时候,不能这样声明,可以使用下面这种

如果想声明被指物不可变,使用const_iterator
std::vector<int>::const_iterator citer = vec.begin();
*citer = 10;//error
citer++;//right

3)函数参数const,不让内部改变参数属性;
返回值const,一些可能的bug可以避免,如(a*b)=c的错误

4)const成员函数:允许const属性的重载

4、确认对象被使用前已经被初始化

构造,析构,赋值
5、了解C++默默编写并调用哪些函数
构造函数(T()),析构(~T()),拷贝构造(T(const T& rhs)),复制函数(T &operator=(const T& rhs))

6、若不想使用编译器自动生成的函数,就该明确拒绝
拷贝构造,复制函数声明为private且不定义

7、为多态基类声明virtual析构函数
防止资源泄漏(保证子类析构函数被调用)

8、别让异常逃离析构函数
异常时终止或者吞下
将可能抛出异常的代码提供给用户管理

9、绝不在构造和析构过程中调用virtual函数
构造和析构期间不要调用virtual函数,因为这类调用不会下降到子类的虚函数
原因:
子类构造前,先构造父类;父类调用虚函数,只能调用父类自己的函数,因为子类还没有构造;
同理,子类析构,先析构自己,然后析构父类,当父类析构函数调用虚函数,不可能指向子类的虚函数,因为子类已经析构不存在了。
PS:
一个virtual函数,就有一个虚表;虚表是在编译期创建的。
在执行期,根据虚表,程序找到虚函数实现体,实现多态

10、令operator= 返回一个reference to *this
eg:
template <class T>
T& operator=(const T& rhs)
{
...
return *this;
}

11、在operator=中处理“自我赋值”
eg1:
template <class T>
T& operator=(const T& rhs)
{
if(this == &rhs)return *this;
...
return *this;
}
eg2:
copy-and-swap技术
template <class T>
T& operator=(const T& rhs)
{
if(this == &rhs)return *this;
//copy-and-swap
bitmap* pOrig = pb;
pb = new bitmap(*rhs.pb);
delete pOrig;
//
return *this;
}

12、复制对象时勿忘期每一个成分
如果是子类赋值函数或者是复制构造函数,除了复制子类所有成员变量;
需要适当调用父类的对应函数,父类不满足;父类也需要重新这些函数
eg见代码effective12

资源管理
13、以对象管理资源
构造函数获得资源,析构函数释放资源;
使用智能指针封装:tr1::shared_ptr和auto_ptr。
关于智能指针,见另外一片blog

14、在资源管理类中小新copying行为

15、在资源管理类中提够对原始资源的访问
原始资源获取;
显式转换安全
隐式转换——对客户方便,不安全

16、成对使用new和delete时采用相同形式
new, delete
new [], delete []

17、以独立语句将newed对象置入智能指针
eg:
std::tr1::shared_ptr<T> pw(new T);
processT(pw,test())
代替
processT(std::tr1::shared_ptr<T>(new T),test())

防止test()出现异常,new T之后没有调用tr1::shared_ptr出现资源泄漏

设计与声明
18、让接口容易被正确使用,不易被误用

 待续

Effective C++ 笔记