【Effection C++】读书笔记 条款10~条款12

【Effection C++】读书笔记 Part2 构造/析构/赋值运算

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

构造函数和析构函数期间不要调用virtual函数,虽然语法上并不会有错误。但是在一个派生类的基类成分构造期间,对象的类型永远是基类而不是派生类。包括使用typeid或者dynamic_cast都会将对象视为基类类型,所以其调用的虚函数是永远不会下降到派生类的。

对于析构函数也有着类似的行为,派生类的成员在析构的时候,其类型也是随着析构函数的执行而不断变化,先是派生类类型然后是基类类型。

如果基类构造函数需要派生类的信息,可以通过派生类构造函数时候,将必要的信息传送到基类的构造函数。

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

为了实现连锁赋值,赋值运算符必须返回一个reference指向操作符的左侧实参。

class Widget
{
public:
    Widget & operator=(const Widget &rhs)
    {
        ...
        return *this;
    }
}

Widget d1,d2,d3;
d1 = d2 = d3;   //实现连锁赋值

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

  1. 确保当对象自我赋值的时候operator=有良好行为。其中技术包括比较:
    1. 比较源对象和目标对象的地址,可以保证自我赋值,但是可能无法保证异常安全
    2. 设置语句程序使得保证自我赋值和异常安全性
    3. copy-and-swap技术
  2. 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时候,其行为仍然正确。

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

  1. Copying函数应该确保复制“对象内的成员变量”及“所有base class成分”。
  2. 不要尝试以某个coying函数实现另外一个函数,应该将所有共同机能放进第三个函数中,并由两个copying函数共同调用。

class Cutsomer  
{  
……  
private:  
    string name;  
    string telphone;  
};  

class PriorityCustomer:public Cutsomer  
{  
public:  
    PriorityCustomer()  {  }  
    PriorityCustomer(const PriorityCustomer& rhs);
    PriorityCustomer& operator=(const PriorityCustomer& rhs);

private:  
    int priority;  
};

PriorityCustomer(const PriorityCustomer& rhs)  
        :Cutsomer(rhs),priority(rhs.priority)  //拷贝初始化初始化基类部分
{  
    cout<<"PriorityCustomer Copy Ctor"<operator=(const PriorityCustomer& rhs)  
{  
    cout<<"PriorityCustomer assign operator"<//对基类对象进行赋值操作
    Cutsomer::operator=(rhs);  
    priority=rhs.priority;  
    return *this;  
}  

你可能感兴趣的:(读书笔记,effective-c++,c++)