- explicit 可以用来阻止隐式类型转化
- 如果类成员变量里面存在const 或 引用数据成员,则拷贝赋值函数,即operator =,需要自己重写,不可以用默认拷贝赋值;如果有成员变量有指针,视具体情况而定。
- 为驳回编译器默认的提供的机能,可将相应的成员函数声明为private并且不予实现。使用像Uncopyable这样的base class也是一种做法
- 带有多态性质的base class(即有一个或一个以上virtual 成员函数),应该声明一个virtual 析构函数
- 析构函数绝对不要吐出异常,如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们或结束程序
- 在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class
- 令赋值assignment操作符返回一个 reference to *this,这样可以链式赋值
public:
Widget & operator=(const Widget & rhs)
{
...
return *this;
}
8.在operator = 中处理自我赋值,
方法一:这样做每一次都需要判断一次,降低了效率
Widget & operator =(const Widget &rhs)
{
if( & rhs== this)return *this;
delete pb;
pb=new Bitmap(*rhs.pb);
return *this;
}
方法二:这样效率最佳
Widget & operator =(const Widget &rhs)
{
Bitmap *pOrig = & pb;//记住原来的pb
pb=new Bitmap(*rhs.pb);
delete pOrig;//删除原来的pb
return *this;
}
9.任何时候,只要你承担起为derived class撰写copy函数的责任,你就要必须很小心的也复制其based class 成员变量,这些变量往往是private的,所以往往无法访问,应该让derived class 调用based class 的相应的函数,eg:
Derived::Derived(const Derived & rhs)
:Based( rhs ),//调用based class 的拷贝构造函数
priority( rhs.priority)
{
log("copy");
}
Derived& Derived:: operator=(const Derived & rhs)
{
Based::operator=(rhs);//对based 成分进行赋值操作
priority=rhs.priority;
return *this;
}
- 不要令copy assignment 操作符调用copy构造函数,也不要用copy构造函数调用 copy assignment 操作符,如果有重复代码,应该提取到init函数共同使用
11.auto_ptr 智能指针与 shared_ptr 引用计数智能指针
auto_ptr指针所指对象拥有唯一拥有权
std:: auto_ptr<Investment> pInv1(creatInvestment());
std:: auto_ptr<Investment> pInv2(pInv1);//pInv2获取对象,pInv1变为null
pInv1=pInv2;//pInv1获取对象,pInv2变为null
shared_ptr可以多个指针同指一个对象,当没有指针指向该对象时,对象的内存会自动释放
void f()
{
std::tr1::shared_ptr<Investment> pInv1(creatInvestment());//
std::tr1::shared_ptr<Investment> pInv2(pInv1);//pInv1和pInv2指向同一对象
pInv2=pInv1;//同上
}//pInv2,pInv1被销毁,对象也被销毁
12.以独立指针将newd对象存入智能指针内。如果不这样做,一旦异常被抛出,就会造成内存泄漏
13.尽量以pass-by-reference-to-const替代pass-by-value
14.绝不要返回一个pointer或reference指向一个local stack对象,或返回一个reference指向一个heap-allocated对象,或返回一个pointer或reference指向一个local static对象而有可能同时需要多个这样的对象
15.如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member函数
class Rational
{
...
public:
const Rational operator *(const Rational &rhs)const;
//这里可以理解为 *this * rhs
};
//假设result和onehalf是Rational类型
result = onehalf*2;//2会隐式转换为Rational,所以正常
result = 2*onehalf;//这里错误,无法通过编译
//如果换成以下函数定义,上面可以通过编译
const Rational operator*(const Rational & lhs,const Rational & rhs)const;