标签:c++
运算符重载包括:双目运算符重载、单目运算符重载、流运算符重载、转换构造函数、类型转换函数
重载运算符的函数一般格式如下:
函数类型 operator 运算符名称 (形参表列)
{
// 对运算符的重载处理
}
双目:有2个操作数的运算符
重载函数可以为类成员函数或者是类的友元函数:
- 当是成员函数时,有一个隐藏参数(当前类),因此只有一个显示参数:如
Complex operator+(const Complex &b);
Complex operator+(const double &d);
- 当是友元函数时,必须显式给出两个参数,之所以使用友元函数,是为了将操作符重载为全局的:
因为
Complex c(1,1);
Complex d = c + 10.0; // 正确
Complex e = 10.0 + c; // 错误
对于第3行,无法从浮点数“10.0”获得如何操作。
因此将重载函数声明为友元函数,则可以全局的对 10.0 和 c 进行参数匹配.
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double real, double imag) {this->real = real;this->imag = imag;}
Complex() {real = 0.0;imag = 0.0;}
// 转换构造函数:只能有一个参数
public:
Complex operator+(const Complex &b);
friend Complex operator+(const Complex &c, const double & d);
friend Complex operator+(const double & d, const Complex &c); // 友元函数可以
void Print() {
if (imag < 0)
cout << real << imag << "i" << endl;
else
cout << real << "+" << imag <<"i" << endl;
}
};
// 成员函数重载
Complex Complex::operator+(const Complex &b) {
return Complex(this->real+b.real, this->imag+b.imag);
}
// 友元函数不能省略参数,重载成一个全局操作符
// 友元函数可以访问友元类的私有成员
Complex operator+(const double &d, const Complex &c) {
return Complex(c.real+d, c.imag);
}
Complex operator+(const Complex &c, const double &d) {
return Complex(c.real+d, c.imag);
}
int main() {
Complex a(1,-2);
Complex b(3,-1);
Complex c = a+b;
Complex f = 10+a;
Complex g = b + 10;
c.Print();
f.Print();
g.Print();
}
重点的讨论自增自减的运算符重载。参考以下程序可以观察到:
前缀式操作符和后缀式操作符重载的区别在于,带有参数 int,以及返回值是不同的:
C++规定:前缀式操作符,返回被增量或被减量对象的引用;后缀式操作符,返回被增量或被减量对象做增或减操作之前的副本
MyClass operator++(); // 前缀式,++i;
MyClass operator++(int); // 后缀式,i++
一个基于Time的类例程如下:
#include <iostream>
using namespace std;
class Time {
private:
int minute;
int sec;
public:
Time():minute(0), sec(0) {};
Time(int m, int s):minute(m), sec(s) {};
// 前缀式操作符,返回被增量或被减量对象的引用;
Time operator++() {
if (++sec >= 60) {
minute++;
sec -= 60;
}
return *this;
}
//后缀式操作符,返回被增量或被减量对象做增或减操作之前的副本
Time operator++(int) {
Time temp(*this);
++(*this);
return temp; // 对象本身已经实现了自增操作,但返回的是未自增之前的副本
}
void print() {
cout << minute << ":" << sec << endl;
}
};
int main() {
cout << "开始时间 12:58" << endl;
Time time1(12, 58);
for (int i = 0; i < 5; i++) {
(++time1).print();
}
cout << "开始时间 22:58" << endl;
Time time2(22,58);
for (int i = 0; i < 5; i++) {
(time2++).print();
}
}
对“<<”和“>>”重载的函数形式如下:
istream & operator >> (istream &, 自定义类 &);
ostream & operator << (ostream &, 自定义类 &);
即重载运算符“>>”的函数的第一个参数和函数的类型都必须是istream&类型,第二个参数是要进行输入操作的类。重载“<<”的函数的第一个参数和函数的类型都必须是ostream&类型,第二个参数是要进行输出操作的类。因此,只能将重载“>>”和“<<”的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。
操作符重载之所以有返回值是为了返回输入/输出的状态,以便连续的输入输出。
详细参见:http://c.biancheng.net/cpp/biancheng/view/220.html
代码案例参考双目运算符中的代码块。
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double real, double imag) {this->real = real;this->imag = imag;}
Complex() {real = 0.0;imag = 0.0;}
public:
friend istream& operator>>(istream &, Complex &);
friend ostream& operator<<(ostream &, Complex &);
};
// 流操作符重载
istream& operator>>(istream &input, Complex &c) {
input >> c.real >> c.imag;
return input; // 返回流输入对象,以便连续输入
}
ostream& operator<<(ostream &output, Complex &c) {
output << c.real;
if (c.imag >= 0)
output << "+";
output << c.imag << "i" << endl;
return output;
}
int main() {
Complex x, y;
cin >> x >> y;
cout << x << y;
}
转换构造函数只有一个形参,如
Complex(double r) {real=r;imag=0;}
其作用是将double型的参数r转换成Complex类的对象,将r作为复数的实部,虚部为0。
和操作符重载配合,简化操作符重载的实现.
如下所示,只需要一个操作符 + 的重载和转换构造函数,即可满足所有 + 操作的情况,并满足了交换律。注意上述操作符重载必须为友元函数或者普通函数的形式(非成员函数)。
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double real, double imag) {this->real = real;this->imag = imag;}
Complex() {real = 0.0;imag = 0.0;}
// 转换构造函数:只能有一个参数
Complex(double real) {
this->real = real;
this->imag = 0;
}
public:
friend Complex operator+(const Complex &a, const Complex &b);
void Print() {
if (imag < 0)
cout << real << imag << "i" << endl;
else
cout << real << "+" << imag <<"i" << endl;
}
};
Complex operator+(const Complex &a, const Complex &b) {
return Complex(a.real+b.real, a.imag+b.imag);
}
int main() {
Complex a(1,-2);
Complex b(3,-1);
Complex e = a + b;
e.Print();
Complex f = 10 + a; // 自动将 10 ,转换成Complex的一个实例
f.Print();
Complex g = a + 10;
g.Print();
}
用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成double类型数据)。
C++提供类型转换函数(type conversion function)来解决这个问题。类型转换函数的作用是将一个类的对象转换成另一类型的数据。如果已声明了一个Complex类,可以在Complex类中这样定义类型转换函数:
operator double( )
{
return real;
}
注意:没有函数返回类型,没有参数。返回类型自动根据重载的类型名一致。类型转换函数只能作为成员函数(转换的是本类的对象)。
#include <iostream>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double real, double imag) {this->real = real;this->imag = imag;}
Complex() {real = 0.0;imag = 0.0;}
operator double() {
return real;
}
public:
void Print() {
if (imag < 0)
cout << real << imag << "i" << endl;
else
cout << real << "+" << imag <<"i" << endl;
}
};
int main() {
Complex a(1,-2);
Complex b(3,-1);
double d = a + 10;
cout << d << endl;
cout << a + 10 << endl;
cout << 10 + b << endl;
}
标签:c++
原文地址:http://blog.csdn.net/quzhongxin/article/details/46640135