运算符重载的方法是定义一个运算符重载函数,也就是说,运算符重载函数是通过定义一个函数来实现的,运算符重载实质上是函数的重载。运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
自定义类的赋值运算符重载函数的作用与内置赋值运算符的作用类似,但是要注意的是,它与拷贝构造函数与析构函数一样,要注意深拷贝浅拷贝的问题,在没有深拷贝浅拷贝的情况下,如果没有指定默认的赋值运算符重载函数,那么系统将会自动提供一个赋值运算符重载函数。
**所谓重载,就是赋予新的含义。**实际上我们在前期的学习过程中已经不知不觉使用了运算符重载,如"<<“和”>>“本来是c++的位移运算符,但是却可以用来输入与输出,这是因为c++系统对”<<“和”>>"运算符进行了重载,用户在不同的场合下使用它们,作用是不同的。
函数类型 operator 运算符名称(形参列表)
函数类型 operator 运算符名称(形参列表)
在上面的格式中,operator是c++的关键字,是专门用于定义重载运算符的函数的,运算符名称就是c++已经有的运算符。注意:函数名是由operator和运算符组成
1.c++不允许用户自己定义新的运算符,只能对已经有的运算符进行重载。
2.c++允许重载的运算符
双目关系运算符:+,-,,/,%
关系运算符:==,!=,<,>,<=,>=,
逻辑运算符:||,&&,!
单目运算符:+,-,指针,&
自增自减运算符:++,–
位运算符:|,&,~,^,<<,>>
赋值运算符:=,+=,-=,=,/=,%=,&=,|=,^=,<<=,>>=
空间申请与释放:new,delete,new[],delete[]
其他运算符:()函数调用,->,->,逗号,[]下标
c++中不能重载的运算符有五个
.(成员访问运算符),(成员指针访问运算符),::(域运算符),sizeof(长度运算符),?:(条件运算符)
3.重载不能改变运算符运算对象的个数
4.重载不能改变运算符的优先级
5.重载不能改变运算符的结合性
6.重载运算符的函数不能有默认的参数
7.重载的运算符必须和用户定义的自定义类型的对象一起使用,** 其参数至少应有一个使类对象 或类对象的引用 **
也就是说,参数不能全部使c++的标志类型,以防止用户修改用于标准运算符的性质。
8.用于类对象的运算符一般必须重载,但是有两个例外,运算符“=”和运算符“&”。“=”可以用于每个类对象,这是因为系统已经为每一个新声明的类重载了赋值运算符,它的作用是逐个复制类对象的成员。&也不必重载,它能返回对象在内存中的地址。以上这些规则是很容易理解的,不必死记。
(1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中含有两个参数,对单目运算符而言,成员运算符重载函数参数表中没有参数而友元运算符重载函数参数表中含有两个参数。
(2)双目运算符一般可以被重载为友元运算符重载函数或成员运算符重载函数,但有一种情况,必须使用友元函数.
1.c++规定,赋值运算符=,下标运算符1,函数调用运算符(),成员运算符->必须作为成员函数重载。
2.流插入运算符“<<”和流提取运算符“>>”,类型转换运算符函数不能作为类的成员函数,只能作为友元函数。
3.一般将单目运算符和复合运算符重载为成员函数。
4.一般将双目运算符重载为友元函数。
#include
using namespace std;
class Distance
{
private:
int feet;
int inches;
public:
Distance() { feet = 0; inches = 0; } //赋值为0
Distance(int f, int i) { feet = f; inches = i; } //构造函数
void showdistace() //显示距离
{
cout << "f:" << feet << ",i:" << inches << endl;
}
Distance operator-()
{
feet = -feet;
inches = -inches;
return *this; //return Disrance(feet,inches)
}
};
int main()
{
Distance d1(1, 10), d(-5, 110);
-d1;
d1.showdistace();
- d;
d.showdistace();
return 0;
}
#include
using namespace std;
class Box
{
private:
double length;
double wideth;
double height;
public:
Box() { length = 0; wideth = 0; height = 0; }
Box(int a, int b, int c)
{
length = a;
wideth = b;
height = c;
}
double show()
{
return length * wideth * height;
}
//重载运算符+,用于把两个B0X对象加起来
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.wideth = this->wideth + b.wideth;
box.height = this->height + b.height;
return box; //不能return *this
}
};
int main()
{
Box b(3, 4, 5);
Box b1(4, 5, 6);
cout << b.show() << endl;
cout << b1.show() << endl;
Box b3;
b3 = b1.operator+(b);
cout << b3.show() << endl;
}
#include
using namespace std;
class Complex
{
private:
double real;
double imag;
public:
Complex() {}
Complex(double r, double i)
{
real = r;
imag = i;
}
Complex operator+(Complex& c1)
{
Complex c;
c.real = real + c1.real;
c.imag = imag + c1.imag;
return c;
}
void show()
{
cout << "(" << real << "," << imag << ")" << endl;
}
};
int main()
{
Complex c(3, 4), c1(5, 5), c2;
c.show();
c1.show();
c2 = c1.operator+(c);
c2 = c + c1;
c2.show();
c2.show();
}
#include
using namespace std;
class Rect
{
private:
double width;
double height;
public:
Rect(double a, double b)
{
width = a;
height = b;
}
double area()
{
return width * height;
}
//重载小于运算符,按照面积比大小
bool operator<(Rect& that) // 不能用Rect
{
return this->area() < that.area();
}
};
int main()
{
Rect r1(3, 4), r2(4, 5);
cout << r1.area() << endl;
cout << r2.area() << endl;
if (r1 < r2)
{
cout << "r2大" << endl;
}
else
cout << "r1大" << endl;
return 0;
}
可以把运算符重载函数声明为类的友元函数,这样就可以不用创建对象而直接调用函数.
1、ostream后面的out是可以换的,这里换成什么,后面的函数体就要换成什么,比如说这里改为ostream&output,那么后面的函数体就要都变成output<
#include
using namespace std;
class Rect
{
private:
double width;
double height;
public:
Rect() { width = 0; height = 0; }
Rect(double a, double b)
{
width = a;
height = b;
}
double area()
{
return width * height;
}
//重载小于运算符,按照面积比大小
friend ostream& operator<<(ostream& output, Rect& r) //固定格式
{
output << "width" << r.width << endl;
output << "height" << r.height << endl;
output << "area" << r.area() << endl;
return output; //返回流的引用
}
friend istream& operator>>(istream& input, Rect& r)
{
input >> r.width >> r.height;
return input; //返回流的引用
}
};
int main()
{
Rect r1(3.0, 4.0), r2(6.0, 8.0),r3;
cin >> r3;
cout << r1 << endl;
cout << r2 << endl;
cout << r3 << endl;
}
#include
using namespace std;
class Time
{
private:
int minuate;
int second;
public:
Time() { minuate = 0; second = 0; }
Time(int m, int s)
{
minuate = m; second = s;
}
void display()
{
cout << minuate << " : " << second << endl;
}
//前缀++
Time operator++()
{
second++;
if (second >= 60)
{
minuate++;
second = 0;
}
return *this;// Time(minuate, second);
}
//后缀++
Time operator++(int)
{
Time t(minuate, second); //保存原始数据
second++; //对象加1;
if (second >= 60)
{
minuate++;
second = 0;
}
return t; //返回旧的原始值
}
};
int main()
{
Time t1(12, 58), t2(0, 45);
t1.display();
(++t1).display();
(++t1).display();
t2.display();
(t2++).display();
(t2++).display();
return 0;
}