Effective C++学习---02.构造/析构/赋值运算

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

  • 编译器默认为class创建default函数,拷贝构造函数、赋值(=)运算符以及析构函数(用户未定义同类函数,且代码中有调用)
  • 类中包含引用时,需要手动编写赋值运算符,因为对编译器而言,不允许修改引用使其指向其他地址;类中包括常量;类中某些成员变量或基类不支持赋值语句;对于编译器不支持的操作,是无法默认生成对应函数的

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

  • 由条款05知道,编译器会默认生成拷贝构造函数、赋值(=)运算符,所以如果不想编译器生成该类函数时,应该明确指出
  • 将某些成员函数定义为private,而不实现它,这样可以避免友元误调用,编译时会出现链接错误,也可以直接有delete关键字声明

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

  • 避免出现“局部销毁”,通过基类指针delete,导致基类资源被释放,而子类资源未释放
  • 如果一个类带有任何一个virtual类型的函数时,最好将析构函数声明为virtual
  • 设计基类时需要考虑其是否具有多态性,即考虑清楚是否要将析构函数设置为virtual
  • 如果继承别的类时,要考虑清楚是否会通过该类的指针调用继承类,即确定别的类的析构函数是否为虚函数

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

  • 在析构函数中发生异常时,最好进行捕获,记录并调用std::abort()提前终止程序或者对异常进行处理,保证异常不会从析构函数中传播出去
  • 对于析构函数中可能会出现的异常,最好提供一个成员函数来处理可能会出现异常的语句,这会在程序中,可以通过调用该接口提前处理异常,而不是将其延迟到析构函数中

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

  • 在基类构造期间,virtual函数不是virtual函数,在父类的构造函数中调用的虚函数是父类的虚函数,而不是子类的虚函数,但是实际是构造子类,调用的虚函数应该是子类的虚函数;(更一般的理解,父类构造时,此时的虚表地址是父类的虚表地址而不是子类的虚表地址)
  • 在父类的构造函数和析构函数中,只允许访问父类的资源,而不允许访问子类的资源,因此子类的资源沿未初始化或已经被释放,被访问的话会导致未定义行为

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

  • 令赋值操作符返回一个引用reference(*this),+=,-=也一样

条款11:在operator=中处理“自我赋值”

  • 即operator=左右均是一个对象
//自我赋值安全且异常安全

class Bitmap {};
class Widget
{
public:
    Widget& operator=(const Widget& rhs)
    {
        //没有判断&ths与this的关系,可以添加,但需要评估
        //自我赋值的次数与添加判断带来的损失
        Bitmap* pOrig = pb;
        pb = new Bitmap(*rhs.pb);    //new异常安全,这样new不成功的话,
                                     //*this管理的资源不会被释放
        delete pOrig;
        return *this;
    }
private:
    Bitmap* pb;
};

条款12:复制对象时勿忘其每一个成分

  • 尤其是在子类调用拷贝构造函数时,应该对其父类也调用拷贝构造函数
  • 最好不好在赋值操作符中调用拷贝构造函数
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值