1.首先,我们先明确什么符号是不能重载的:sizeof、::、?:、.、.*这五类是不能重载的。我们也不能定义新的运算符。
2.其次,我们要明确,我们如何重载运算符:成员函数,友元函数。
3.已知2,那么这两种方法的能力一样吗?请见4
4.友元无法重载=、()、[]、->,当然,区别不只是这些,请见5
5.成员函数由于可以走后门,所以可以将参数个数减1,身为朋友的友元函数也只是朋友而已,明算账,该是几个就是几个。同时,由于友元函数会破坏类的封装性和数据的隐蔽性,但又会提高程序的运行效率,所以要权衡利弊进行使用。
6.注意,在重载插入运算符"<<"和提取运算符">>"时,应该注意到using namespace std,否则就会出现bug。
下面的代码直接拿去运行,注意我的注释,可以减少你的很多bug。
#include<iostream> using namespace std; class complex { private: double r; double i; public: complex(double a = 0, double b = 0):r(a), i(b) {}//注意,此时不能再定义无参构造函数,否则会发生冲突 complex operator+(const complex& c)//“+”是双目运算符 { complex t; t.r = r + c.r; t.i = i + c.i; return t; } complex operator+(double d) { complex t; t.r = r + d; t.i = i; return t; } complex operator-(const complex& a);//注意成员函数在类外定义和友元函数的不同之处 complex& operator=(const complex& a) { if (this != &a) { r = a.r; i = a.i; } return *this; } friend complex operator+(const complex& a, const complex& c) { complex t; t.r = c.r + a.r; t.i = c.i + a.i; return t; } friend complex operator+(double d, const complex& c); friend ostream& operator<<(ostream& os, const complex& c) { os << "r:" << c.r << "i:" << c.i; return os; } void print(); }; complex complex::operator-(const complex& a) { complex t; t.r = r - a.r; t.i = i - a.i; return t; } void complex::print() { std::cout << r << " " << i << std::endl; } complex operator+(double d, const complex& c) { complex t; t.r = c.r + d; t.i = c.i; return t; } int main() { complex a(3, 5), b(4, 9), c; c = a+10.5;//由友元函数护航,成员函数无能为力 c.print(); c = a; c.print(); cout << a; return 0; }
续:
下面要提一嘴前后缀的问题了。
对比:前缀++返回的是一个引用,因此,并没有生成临时对象的开销,性能较高;相比之下,后缀++返回的是一个临时对象。所以,在写这两种重载函数时要注意到形式问题。
complex& complex::operator++()//用成员函数定义前缀++
{
r++;
i++;
return *this;
}
complex complex::operator++(int dummy)//用成员函数定义后缀++
{
complex oldval(*this);
r++;
i++;
return oldval;
}