Effective C++学习第四天

条款11:在operator=中处理自我赋值的现象

           虽然我们在平时可能不会出现显示自我赋值的现象,当加入指针或者引用时,可能会出现不同的指针或引用指向同一对象(对象的不同别名),这时候我们就得考虑对象是否是同一个;考虑到要保证系统的自我赋值安全性和异常安全性的角度,可以采用的方案是:将原来的被赋值对象做一个副本,然后让被赋值对象指向复制对象,最后删除副本即可,代码如下:

        widget& widget::operator=(const widget & rhs){

                    bitmap *porig=pb;                          //pb为类widget的一个类型为bitmap的指针

                    pb=new  bitmap(*rhs.pb);

                    delete porig;

                    return *this;

          }

           最好的方法是采用copy and swap的方案,代码如下:(方案1采用传引用的方法,方案2采用传值的方法

       void swap(widget &rhs)  {....};    //交换rhs和*this的数据;

    方案1: widget &widget::operator=(const widget & rhs){              方案2: widget&widget::operator=(widget rhs)

                    widget temp(rhs);                                                      {   

                    swap(temp);                                                                                   swap(rhs);                                            

                   return *this;                                                                                    return *this;

      }                                                                                              }

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

          当自己定义copy函数时(copy构造和copy assignment),编译器不再给我们提供新的copy函数,因此在拷贝的过程中,我们要确定所有的成员变量都被拷贝;

          当我们为class增添新的成员变量时,我们需要修改我们所有的copy函数,构造函数,采用继承的方式可以避免代码的过多修改,但是你必须保证base class的成员变量也被初始化,也就是在derived class的拷贝函数初始化列表或者函数体中调用base class的拷贝函数;如果不这样做,derived class在构造copy函数的时候会调用base class的default copy函数,但是base class的copy函数是被阻止的,因此此时编译器会报错;

         结论:当我们写一个自定义的copy函数的时候,确定几点:1)复制所有的local成员变量;2)调用所有base class内适当的copy函数;

            不要令copy assignment去调用copy构造函数;也不要让copy构造函数去调用copy assignment;

           当copy assignment和copy 构造函数有相近的代码时,可以把相同的代码变成新的成员函数,这样的函数通常为private且常命名为init;

条款13:以对象管理资源

             以singleton(单例模式)的factory function为例,函数返回的是一个heap-base的指针,用户在使用完这个对象之后需要把这个指针删除,如何保证这个指针所指向的资源被删除呢?可选用的方法是把:把资源放进对象中,利用C++的“析构函数自动调用机制”保证资源被释放;

             C++标准程序库中提供auto_ptr(类指针对象,也称为智能指针),其析构函数自动对其所指对象调用delete,常见的智能指针有unique_ptr,shared_ptr;weak_ptr;

            以对象管理资源的两个关键想法:1)获得资源后立刻放进管理对象内,实际上“以对象管理资源”的观念通常被称为“资源取得时机便是初始化时间(resource acquisition isinitialization RAII)”;2)管理对象运用析构函数确保资源被释放(在析构函数释放资源时,可能会出现异常,正确处理析构函数中抛出异常的情况);

            auto_ptr的特性是被销毁(调用copy函数时会发生)时自动删除它的所指之物,并将自己的指针指向nullptr,因此不要让对个auto_ptr指向同一个对象,如果这样可能会出现对象被删除一次以上;auto_ptr的性质是始终只有一个指针取得资源的唯一拥有权;

          auto_ptr的替代方案是:引用型计数指针(reference-counting smart pointer,RCSP),该指针特性就是持续追踪多个指针指向同一资源,并在无人指向该资源时释放资源,但是RCSP无法打破环形引用(也就是类中互相指向的问题,可用weak_ptr来解决这一现象);

         由于以对象管理资源在析构函数中执行的是delete而非delete[],因此动态分配的数组无法通过这种方式来实现内存释放,只能通过自己手工释放内存资源;

猜你喜欢

转载自blog.csdn.net/xx18030637774/article/details/80781016