操作符
摘要
操作符的重载带给我们极大的便捷,但是,重载操作符的调用时机、 调用方法、他们的行为、他们和其他操作符的关系、以及如何夺取操作符的控制权都是需要关注的点。
对定制的“类型转换函数”保持警觉
- 隐式类型转换的两种函数:单变量的构造函数和隐式类型转换操作符。
- 所谓单变量的构造函数指能够以单个自变量调用的构造函数,(自变量就只有一个;多个自变量,除一个外均有默认值)
class Name { public: Name(const std::string ); } class People { public: People(int age, std::string name="Tom"); } - 所谓隐式类型转换操作符,为关键词operator后加一个类型转换名称的成员函数,无需指定函数的返回类型,因为类型已经通过函数名称知名
class Ration
{
public:
....
operator double() const;
}
- 最好不要提供任何隐式类型转换函数,因为该函数的调用时机可能是未打算也未预期的。可以通过定义函数实现相应的功能(如 asDouble)来避免隐式类型转换操作符的隐式转换;可以通过在构造函数前增加关键字explict来避免单变量的构造函数的隐式转换。
- 没有任何一个转换程序可以内含一个以上的“用户定制转换行为”,如int->arrSize,继而arrSize->Array<int>
区分自增自减操作符的前置后置形式
-
前置操作符无参数,后置操作符有参数。
前置返回引用,后置返回const对象。
前置先计算后取出;后置先取出后计算 后置表达式需要构造一个临时变量,需要构造、析构,效率差,建议使用前置。 在实现自己类重载时,后置表达式的实现要依赖前置表达式,可以减少维护成本
class UPInt
{
public:
....
UPInt& operator++()
{
*this +=1;
return *this;
}
const UPInt operator++(int)
{
UPInt oldValue = * this;
++(*this);
return oldValue;
}
}
不要重载 && || ,操作符
- && || 两个个操作符均满足“骤死式”,如&&前的表达式为false时,表达式不会计算。
- ,操作符的行为:先评估左侧,在评估右侧,最后整个表达式的结果以逗号右侧的的值为代表
- 重载以上两个操作符便打破了这些操作符的内建行为。
- 不可以重载的操作符如下:
. .* :: ?: new delete sizeof typeid static_cast dynamic_cast const_cast reinterpret_cast
了解各种意义的new和delete
- new操作符:即堆上分配内存并调用构造函数的。
- 操作符new:重载new操作符时的函数名称
程序员本身是可以调用operator new操作用,类似于mallocvoid* operator new(size_t size) {}void* rawMemory = operator new(sizeof(std::string)); - placement new用于在分配好的内存上构建对象。
如果希望对象生成于堆上,用new操作符,分配内存+调用构造函数
如果只分配内存:用operator new,不会调用构造函数,如果希望自己决定内存分配方式,书写自己的operator new
如果在已经分配内存中构造对象,则用placement new
- delete操作符和操作符delete等同于new操作符和操作符new
- 操作符 new[] 操作符 delete[]