more effective C++ 读书笔记--操作符

122 阅读3分钟

操作符

摘要

操作符的重载带给我们极大的便捷,但是,重载操作符的调用时机、 调用方法、他们的行为、他们和其他操作符的关系、以及如何夺取操作符的控制权都是需要关注的点。

对定制的“类型转换函数”保持警觉

  1. 隐式类型转换的两种函数:单变量的构造函数和隐式类型转换操作符。
  2. 所谓单变量的构造函数指能够以单个自变量调用的构造函数,(自变量就只有一个;多个自变量,除一个外均有默认值)
    class Name
    {
     public:
         Name(const std::string );
    }
    
    class People
    {
     public:
         People(int age, std::string name="Tom");
    
    }
    
  3. 所谓隐式类型转换操作符,为关键词operator后加一个类型转换名称的成员函数,无需指定函数的返回类型,因为类型已经通过函数名称知名
class Ration
{
    public:
    ....
    operator double() const;
}
  1. 最好不要提供任何隐式类型转换函数,因为该函数的调用时机可能是未打算也未预期的。可以通过定义函数实现相应的功能(如 asDouble)来避免隐式类型转换操作符的隐式转换;可以通过在构造函数前增加关键字explict来避免单变量的构造函数的隐式转换。
  2. 没有任何一个转换程序可以内含一个以上的“用户定制转换行为”,如int->arrSize,继而arrSize->Array<int>

区分自增自减操作符的前置后置形式

  1. 前置操作符无参数,后置操作符有参数。
    前置返回引用,后置返回const对象。
    前置先计算后取出;后置先取出后计算 后置表达式需要构造一个临时变量,需要构造、析构,效率差,建议使用前置。 在实现自己类重载时,后置表达式的实现要依赖前置表达式,可以减少维护成本

class UPInt
{
public:
....
UPInt& operator++()
{
    *this +=1;
    return *this;
}
const UPInt operator++(int)
{
    UPInt oldValue = * this;
    ++(*this);
    return oldValue;
}
}

不要重载 && || ,操作符

  1. && || 两个个操作符均满足“骤死式”,如&&前的表达式为false时,表达式不会计算。
  2. ,操作符的行为:先评估左侧,在评估右侧,最后整个表达式的结果以逗号右侧的的值为代表
  3. 重载以上两个操作符便打破了这些操作符的内建行为。
  4. 不可以重载的操作符如下:
    . .* :: ?: new delete sizeof typeid 
    static_cast dynamic_cast const_cast    reinterpret_cast
    

了解各种意义的new和delete

  1. new操作符:即堆上分配内存并调用构造函数的。
  2. 操作符new:重载new操作符时的函数名称
    void* operator new(size_t size)
    {}
    
    程序员本身是可以调用operator new操作用,类似于malloc
    void* rawMemory = operator new(sizeof(std::string));
    
  3. placement new用于在分配好的内存上构建对象。

如果希望对象生成于堆上,用new操作符,分配内存+调用构造函数
如果只分配内存:用operator new,不会调用构造函数,如果希望自己决定内存分配方式,书写自己的operator new
如果在已经分配内存中构造对象,则用placement new

  1. delete操作符和操作符delete等同于new操作符和操作符new
  2. 操作符 new[] 操作符 delete[]