Effective C++ 条款8~12

条款8.异常不要逃离析构函数
在RASII思想中,析构函数总是起到释放资源的作用,从而实现资源管理的目的。但是在资源释放的过程中,难免出现失败的情况,这种情况下析构函数会传播异常,造成难以驾驭的麻烦。

解决方案:
1.abort退出
DBConn::~DBConn(){
    try{
        db.close();
    }catch(...){
        logs.ERROR(e);
        std::abort();    //程序直接退出
        }
    }
2.在方案1的代码中删除abort(),保证程序正确的执行
3.使用者决定析构函数中究竟是否需要释放资源
//bool标志位    对于对象来说不是线程安全的方案???

结论:
析构函数应该抛出异常(不传播异常),而非不考虑异常的出现(导致异常从析构函数中脱离)

-
条款9.构造函数或者析构函数中绝不调用virtual函数

原因:
    在构造derived class对象时,在构造其base class成分时候其virtual函数就被构造了。base class构造期间的virtual函数绝对不会下降到derived class层面。
后果:
    base class中没有进实现的话,编译器会报错。
    但是如果base class也有一份对virtual函数的实现,那么会导致在你构造derived class对象后调用到错误版本的virtual 函数。
    P51  还有些细节

-
条款10.operator=返回reference to *this

//目的: 为了实现连锁赋值
//猜测: operator=本来就是操作两份对象,如果不按照引用返回则又涉及到递归的调用?? 
Widget& operator=(const Widget& rhs){
    //申请资源或者赋值
    return *this;
}

-
条款11.处理operator自我赋值
operator= 操纵的是两个对象 仔细理解!!

class Bitmap{....};
class Widget{
private:
    Bitmap* pb;
}

//不安全的实现版本
Widget& Widget::operator=(const Widget& rhs){
    delete pb;     //等价于delete this->pb;
    pb = new Bitmap(*rhs.pb)
    return *this;
}
//如果 rhs 和 *this是同一份对象,即如果出现自我赋值,那么在delete之后,会使得自己持有对象指向已被删除的对象!

//解决方案1:
Widget& Widget::operator(const Widget& rhs){
    if(this == &rhs) 
        return *this;
    delte this->pb;
    this->pb = new Bitmap(*rhs.pb);
    return *this;
}
//评价: new失败仍然会导致异常安全性错误,返回指向被删除空间的指针

//解决方案2:
Widget& Widget::operator(const Widget& rhs){
    Bitmap* pOrigin = this->pb;
    this->pb = new Bitmap(*rhs.pb);
    delete pOrigin;
    return *this;
}
//评价:避免的new失败导致的异常安全性错误
//过程:对于bitmap做一份福建,删除原有bitmap,指向新制造的复件

总结:
operator= 需要注意到
1.比较rhs和目标对象的地址 2.精心周到的语句顺序 
当我们自我复制的概率很低时候   更需要注意申请资源的new操作的失败的可能性  特别是异常的抛出。保证指针不能指向被删除的地址空间。

-
条款12.复制对象不要忘了每一个成分
解决:
derived class copying函数往往无法直接对于base class的成分进行初始化,因为这些成分往往是private。
应该让derived class 调用相应的base class函数。

PriorityCustomer::PrioriCustomer(const PriorityCustomer& rhs)
:Customer(rhs),        //调用baseclass的copy构造函数
priority(rhs.priority){
}

//operator=调用copy构造函数是很不合理的:毕竟operator操作的是两个已经存在的对象。copy构造函数目的是创建新对象。
copying函数应该确保复制对象内所有的成员变量 以及 所有base class成员
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值