复数的问题
上节课复数的类问题,重载最重要的意义之一就是可以拓展系统当中的功能
但是面对这个复数的加法,编译器肯定不知道怎么办,所以结合前面的友元等一些知识,利用函数显示加法来实现这一功能
#include <iostream>
#include <string>
using namespace std;
class Complex
{
private:
int a;
int b;
public:
Complex()
{
a = 0;
b = 0;
}
Complex(int a, int b)
{
this->a = a;
this->b = b;
}
int getA()
{
return a;
}
int getB()
{
return b;
}
friend Complex add(const Complex& p1, const Complex& p2);
} ;
Complex add(Complex p1, Complex p2)
{
Complex ret;
ret.a = p1.a + p2.a;
ret.b = p1.a + p2.b;
return ret;
}
int main(int argc, char *argv[])
{
Complex c1(1,2);
Complex c2(3,4);
Complex c3 = add(c1,c2);
cout << "c3 = " << "(" << c3.getA() << "," << c3.getB() << ")" << endl;
return 0;
}
这个确实实现了这个功能,但是c3 = add(c1,c2)这种表现形式不好看,而且利用友元也大大破坏了类的封装性。所以总的来看,这样的解决方案也不是最好的解决方案。
思考
Add函数可以解决Complex对象相加的问题,但是Complex是现实世界中确实存在的复数,并且复数在数学中地位和普通的实数相同,那有没有办法让 + 这个操作符也支持复数相加呢?
操作符重载
- C++中能重载操作符的功能
- 操作符重载以函数的方式进行
- 本质:
- 用特殊形式的函数扩展操作符的功能,意思就是写一个函数,这个函数认为是+操作符进行的动作
- 通过operator关键字可以定义特殊的函数
- operator的本质是通过函数重载操作符
- 语法:
Type operator Sign(const Type p1, const Type p2)
{
Type ret;
return ret;
}
Sign为系统中预定义的操作符,如:+,-,*,/,等
复数类代码修改
friend Complex add(const Complex& p1, const Complex& p2);
//改成
friend Complex operator +(Complex p1, Complex p2);
Complex add(Complex p1, Complex p2)
//改成
Complex operator +(Complex p1, Complex p2);
Complex c3 = add(c1,c2);
//先修改成
Complex c3 = operator +(c1,c2);
//再修改成
Complex c3 = c1 + c2;//改成这样就十分完美了,就相当于编译器知道这是复数类相加了
- 但是这种解决方案依然使用了友元
复数类再次修改
- 使用类成员函数来代替全局函数,既保持了类的封装性,又不使用友元
#include <iostream>
#include <string>
using namespace std;
class Complex
{
private:
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
}
int getA()
{
return a;
}
int getB()
{
return b;
}
Complex operator +(const Complex& p)
{
cout << "Complex operator +(Complex& p2)" << endl;
Complex ret;
ret.a = this->a + p.a;
ret.b = this->b + p.b;
return ret;
}
friend Complex operator +(const Complex& p1,const Complex& p2);
} ;
Complex operator +(const Complex& p1, const Complex& p2)
{
cout << "friend Complex operator +(Complex p1, Complex p2);" <<endl;
Complex ret;
ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b;
return ret;
}
int main(int argc, char *argv[])
{
Complex c1(1,2);
Complex c2(3,4);
Complex c3 = c1 + c2;//编译器能自己选择用哪个函数
cout << "c3 = " << "(" << c3.getA() << "," << c3.getB() << ")" << endl;
return 0;
}
这部分代码在从编译器上复制到这篇博客上时,发生了一些小插曲,小插曲在下篇博客里面写。
小结
- 操作符重载是C++的最强大的特性之一
- 操作符重载的本质是通过函数拓展操作符的功能
- operator关键字是实现操作符重载的关键,用operator实现特殊的函数
- 操作符重载遵循相同的函数重载规则
- 全局函数和成员函数都可以实现对操作符的重载
Alipay
Wechat