关于运算符重载:
不允许用户自定义新的运算符, 只能对已有的运算符进行重载
重载运算符不允许改变运算符原操作数的个数
重载运算符不能改变运算符的优先级
重载运算符函数不能有默认的参数, 会导致参数个数不匹配
可以在类内实现, 作为类的成员函数, 也可定义为类的友元函数
当运算符重载函数作为类的成员函数时, 要求操作数左边必须是一个对象, 而函数的参数可以是同类的对象也可以是普通的变量.
- // 作为类成员函数定义:
- Complex operator+(Complex &c1){
- return new Complex(this.real+c1.real,this.image+c1.image);
- }
- // 调用:
(1)c3 = c1+c2; 即 c3 = c1.operator+(c2) // 正确
(2)c3 = c1+5; 函数原型: Complex operator+(int i){} // 正确
(3)c3 = 5+c1; // 错误
这是因为没有办法调用 i.operator+(c1). 那么如果想要这么做, 只能作为类的非成员函数, 而且当要访问的数据为对象的私有成员函数时, 则必须声明为类的友元函数.
总结来说:(1)类的成员函数实现运算符重载, 必须保证左操作数已经处于正确的形式.
(2)全局版本的自动类型 (友元) 转换可以针对左右任意操作数.
(3)各自的优势: 成员函数保证了封装性, 就是指非自身成员不能访问私有成员, 而友元属于非自身成员, 但是赋予他特权来访问类的私有成员, 可以理解为破坏类的封闭性. 但是友元函数实现比较灵活.
所以对于运算符重载, 有必须定义为成员函数的, 比如 [],->,(),= 这四个运算符必须基于对象才能用, 也有的既可以作为类的成员函数, 又可以作为友元函数, 当然也有必须定义成友元函数的, 比如>> 和<<, 因为他们的两个操作数都不是对象本身,
ostream& operator<<(ostream& os, const classType& obj);
则第一个参数是该运算符的第一个操作数, 然而, 却不是类对象, 所以当该类运算符重载时写在类的内部时, 又为了访问类内除 public 外的其它变量或函数,
则应当声明为友元函数:
friend ostream& operator<<(ostream& os, const classType& obj);
另外对于运算符重载时的 const 修饰问题, 我总结下, 有错误的或者不完整的欢迎指正补充
(1)一般形参用引用传递, 因为这样无需在栈内存中开辟空间以装载临时对象, 也省去了复制的耗时过程.
(2)当不希望函数改变形参的值时, 最好用 const 修饰. 不然在引用传递时, 形参改变意味着实参也改变了.
(3)对于函数加 const 修饰的情况, 比如
bool operator<(const node &b) const
那是因为它表示这个函数不会修改该类的任何成员.
如果没有这个 const, 编译器不会允许这个运算符用于一个 const 对象
意思就是没有加 const 的函数不能在 const 对象上使用
来源: http://www.bubuko.com/infodetail-2714785.html