1. 双目复合运算符 1
+= / -= / *=
左值,左操作数的引用;
左变右不变
(a += b) = c;
这里 a 得到 c 的值,b 没起作用;
下面这个例子实现上面这个效果:
Complex{
public:
Complex (int r = 0, int i = 0):m_r(r), m_i(i){}
void print(void) const { // 输出
cout << m_r << '+' << m_r << 'i' << endl;
}
Comples& opeartor+= (const Complex& r) {
m_r += r.m_r;
m_i += r.m_i;
return *this; // 因为返回的是引用,所以这里加星
}
// 用友元实现 -= 操作,这里用了 frined,所以虽然在 Complex 类里面,但是是全局函数
friend Complex& operator-= (Complex& l, const Complex& r) {
l.m_r -= r.m_r;
l.m_i -= r.m_i;
return l; // 返回左值,给c1
}
private:
int m_r;
int m_i;
};
int main(){
Complex c1(1, 2), c2(3, 4);
c1 += c2; // 相当于 c1.operator += (c2);
c1.print();
Complex c3(5, 6);
(c1 += c2) = c3;
c1.print(); // 5+6i
c1 -= c2; // 相当于 ::operator-= (c1, c2);
c1.print(); // (5+6i) - (3+4i) = 2+2i;
(c1 += c2) = c3;
c1.print(); // 5+6i
return 0;
}
操作符重载-成员函数形式:AA& opeartor+= (const AA&);
操作符重载-友员函数形式:friend AA& operator-= (AA&, const AA&);
2. 双目运算符 2
<< / >>
左操作数类型为:ostream/istream,不能是常量,不能拷贝;
右操作数为自定义类型;对于输入,右操作数不能是常量;输出可以;
表达式的值是左操作数的引用;
cout << c << i << endl; 相当于下面表达式:
cout.operator<< (c).operator<< (i).operator<< (endl);
一般用全局/友员方式实现:
::operator<< (cout, c).operator<< (i).operator<< (endl);
因为输入输出是 c++ 标准库里的类函数,不能自己写,所以不能重载成成员函数;
Complex{
public:
Complex (int r = 0, int i = 0):m_r(r), m_i(i){}
void print(void) const { // 输出
cout << m_r << '+' << m_r << 'i' << endl;
}
friend ostream& operator<< (ostream& os, const Complex& r) // 输出,const为了支持常量型操作数
// cout 是私有的,不能拷贝构造,所以给 os 加引用,不创造新对象;
// operator 返回的是当前对象 cout,所以返回值应该加引用;
// 这个函数只是需要打印,不需要创造新对象,所以最后 r 也加引用;既然加了引用,就加 const,可以传常量进来;
{ return os << r.m_r << '+' << r.m_i << 'i'; }
friend istream& operator>> (istream& is, Complex& r) // 输入
{ return is >> r.m_r >> r.m_i; }
private:
int m_r; // 实步
int m_i; // 虚步
};
int main(){
Complex c1(1, 2), c2(3, 4);
cout << c1 << endl << c2 << endl;
//::operator<<(::operator<<(cout,c1)).operator&l
+= / -= / *=
左值,左操作数的引用;
左变右不变
(a += b) = c;
这里 a 得到 c 的值,b 没起作用;
下面这个例子实现上面这个效果:
Complex{
public:
Complex (int r = 0, int i = 0):m_r(r), m_i(i){}
void print(void) const { // 输出
cout << m_r << '+' << m_r << 'i' << endl;
}
Comples& opeartor+= (const Complex& r) {
m_r += r.m_r;
m_i += r.m_i;
return *this; // 因为返回的是引用,所以这里加星
}
// 用友元实现 -= 操作,这里用了 frined,所以虽然在 Complex 类里面,但是是全局函数
friend Complex& operator-= (Complex& l, const Complex& r) {
l.m_r -= r.m_r;
l.m_i -= r.m_i;
return l; // 返回左值,给c1
}
private:
int m_r;
int m_i;
};
int main(){
Complex c1(1, 2), c2(3, 4);
c1 += c2; // 相当于 c1.operator += (c2);
c1.print();
Complex c3(5, 6);
(c1 += c2) = c3;
c1.print(); // 5+6i
c1 -= c2; // 相当于 ::operator-= (c1, c2);
c1.print(); // (5+6i) - (3+4i) = 2+2i;
(c1 += c2) = c3;
c1.print(); // 5+6i
return 0;
}
操作符重载-成员函数形式:AA& opeartor+= (const AA&);
操作符重载-友员函数形式:friend AA& operator-= (AA&, const AA&);
2. 双目运算符 2
<< / >>
左操作数类型为:ostream/istream,不能是常量,不能拷贝;
右操作数为自定义类型;对于输入,右操作数不能是常量;输出可以;
表达式的值是左操作数的引用;
cout << c << i << endl; 相当于下面表达式:
cout.operator<< (c).operator<< (i).operator<< (endl);
一般用全局/友员方式实现:
::operator<< (cout, c).operator<< (i).operator<< (endl);
因为输入输出是 c++ 标准库里的类函数,不能自己写,所以不能重载成成员函数;
Complex{
public:
Complex (int r = 0, int i = 0):m_r(r), m_i(i){}
void print(void) const { // 输出
cout << m_r << '+' << m_r << 'i' << endl;
}
friend ostream& operator<< (ostream& os, const Complex& r) // 输出,const为了支持常量型操作数
// cout 是私有的,不能拷贝构造,所以给 os 加引用,不创造新对象;
// operator 返回的是当前对象 cout,所以返回值应该加引用;
// 这个函数只是需要打印,不需要创造新对象,所以最后 r 也加引用;既然加了引用,就加 const,可以传常量进来;
{ return os << r.m_r << '+' << r.m_i << 'i'; }
friend istream& operator>> (istream& is, Complex& r) // 输入
{ return is >> r.m_r >> r.m_i; }
private:
int m_r; // 实步
int m_i; // 虚步
};
int main(){
Complex c1(1, 2), c2(3, 4);
cout << c1 << endl << c2 << endl;
//::operator<<(::operator<<(cout,c1)).operator&l