可重载运算符/不可重载运算符
下面是可重载的运算符列表:
运算符 | 具体操作符 |
---|---|
双目算术运算符 | + (加),-(减),*(乘),/(除),% (取模) |
关系运算符 | ==(等于),!= (不等于),< (小于),> (大于>,<=(小于等于),>=(大于等于) |
逻辑运算符 | ||(逻辑或),&&(逻辑与),!(逻辑非) |
单目运算符 | + (正),-(负),*(指针),&(取地址) |
自增自减运算符 | ++(自增),--(自减) |
位运算符 | | (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移) |
赋值运算符 | =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>= |
空间申请与释放 | new, delete, new[ ] , delete[] |
其他运算符 | ()(函数调用),->(成员访问),,(逗号),[](下标) |
下面是不可重载的运算符列表:
.
:成员访问运算符.*
,->*
:成员指针访问运算符::
:域运算符sizeof
:长度运算符?:
:条件运算符#
:预处理符号
友元函数/成员函数
只能重载为友元函数(或普通函数)
<<
和>>
的重载必须作为类的友元函数,不能作为成员函数.
运算符重载为成员函数,第一个参数必须是本类的对象。而<<和>>的第一个操作数一定是ostream类型,所以<<
只能重载为友元函数。只能重载为成员函数
有四个操作符必须只能用“成员”函数重载=
()
[]
->
1.一元运算符重载
重载一元减运算符( - ) 即:对一个数取负
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using namespace std;
class Distance
{
private:
int feet; // 0 到无穷
int inches; // 0 到 12
public:
// 所需的构造函数
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
// 显示距离的方法
void displayDistance()
{
cout << "F: " << feet << " I:" << inches <<endl;
}
// 重载负运算符( - )
Distance operator- ()
{
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
};
int main()
{
Distance D1(11, 10), D2(-5, 11);
-D1; // 取相反数
D1.displayDistance(); // 距离 D1
-D2; // 取相反数
D2.displayDistance(); // 距离 D2
return 0;
}++
运算符重载1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using namespace std;
class Time
{
private:
int hours; // 0 到 23
int minutes; // 0 到 59
public:
// 所需的构造函数
Time(){
hours = 0;
minutes = 0;
}
Time(int h, int m){
hours = h;
minutes = m;
}
// 显示时间的方法
void displayTime()
{
cout << "H: " << hours << " M:" << minutes <<endl;
}
// 重载前缀递增运算符( ++ )
Time operator++ ()
{
++minutes; // 对象加 1
if(minutes >= 60)
{
++hours;
minutes -= 60;
}
return Time(hours, minutes);
}
// 重载后缀递增运算符( ++ )
Time operator++( int )
{
// 保存原始值
Time T(hours, minutes);
// 对象加 1
++minutes;
if(minutes >= 60)
{
++hours;
minutes -= 60;
}
// 返回旧的原始值
return T;
}
};
int main()
{
Time T1(11, 59), T2(10,40);
++T1; // T1 加 1
T1.displayTime(); // 显示 T1
++T1; // T1 再加 1
T1.displayTime(); // 显示 T1
T2++; // T2 加 1
T2.displayTime(); // 显示 T2
T2++; // T2 再加 1
T2.displayTime(); // 显示 T2
return 0;
}注意,
int
在括号内是为了向编译器说明这是一个后缀形式,而不是表示整数。
前缀形式重载调用Check operator ++ ()
,后缀形式重载调用operator ++ (int)
。--
运算符重载1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using namespace std;
class Check
{
private:
int i;
public:
Check(): i(3) { }
Check operator -- ()
{
Check temp;
temp.i = --i;
return temp;
}
// 括号中插入 int 表示后缀
Check operator -- (int)
{
Check temp;
temp.i = i--;
return temp;
}
void Display()
{ cout << "i = "<< i <<endl; }
};
int main()
{
Check obj, obj1;
obj.Display();
obj1.Display();
// 调用运算符函数,然后将 obj 的值赋给 obj1
obj1 = --obj;
obj.Display();
obj1.Display();
// 将 obj 赋值给 obj1, 然后再调用运算符函数
obj1 = obj--;
obj.Display();
obj1.Display();
return 0;
}
递增和递减一般是改变对象的状态,所以一般是重载为成员函数。
2.二元运算符重载
二元运算符需要两个参数,下面是二元运算符的实例。我们平常使用的加运算符( + )、减运算符( - )、乘运算符( * )和除运算符( / )都属于二元运算符。
下面示例演示了如何重载加运算符( + )。类似地,您也可以尝试重载减运算符( - )和除运算符( / )。
1 |
|
3.关系运算符重载
C++ 语言支持各种关系运算符( < 、 > 、 <= 、 >= 、 == 等等),它们可用于比较 C++ 内置的数据类型。您可以重载任何一个关系运算符,重载后的关系运算符可用于比较类的对象。
下面的实例演示了如何重载 < 运算符,类似地,您也可以尝试重载其他的关系运算符。
1 |
|
4.输入/输出运算符重载
C++ 能够使用流提取运算符 >>
和流插入运算符 <<
来输入和输出内置的数据类型。您可以重载流提取运算符和流插入运算符来操作对象等用户自定义的数据类型。
在这里,有一点很重要,我们需要把运算符重载函数声明为类的友元函数(也可为普通函数),这样我们就能不用创建对象而直接调用函数。
下面的实例演示了如何重载提取运算符 >> 和插入运算符 <<。
1 |
|
注意返回类型要是一个引用,为了可以连续使用。
5.赋值运算符重载
就像其他运算符一样,您可以重载赋值运算符( =
),用于创建一个对象,比如拷贝构造函数。
下面的实例演示了如何重载赋值运算符。
1 |
|
6.函数调用运算符()
重载
函数调用运算符 ()
可以被重载用于类的对象。当重载 ()
时,您不是创造了一种新的调用函数的方式,相反地,这是创建一个可以传递任意数目参数的运算符函数。
下面的实例演示了如何重载函数调用运算符 ()
。
1 |
|
7.下标运算符 []
重载
下标操作符 []
通常用于访问数组元素。重载该运算符用于增强操作 C++ 数组的功能。
下面的实例演示了如何重载下标运算符 []
。
1 |
|
注意,返回类型也要是个引用。
8.类成员访问运算符 ->
重载
类成员访问运算符( ->
)可以被重载,但它较为麻烦。它被定义用于为一个类赋予”指针”行为。运算符 ->
必须是一个成员函数。如果使用了 ->
运算符,返回类型必须是指针或者是类的对象。
运算符 ->
通常与指针引用运算符 *
结合使用,用于实现”智能指针”的功能。这些指针是行为与正常指针相似的对象,唯一不同的是,当您通过指针访问对象时,它们会执行其他的任务。比如,当指针销毁时,或者当指针指向另一个对象时,会自动删除对象。
间接引用运算符 ->
可被定义为一个一元后缀运算符。也就是说,给出一个类
1 | class Ptr{ |
类 Ptr 的对象可用于访问类 X 的成员,使用方式与指针的用法十分相似。例如:
1 | void f(Ptr p ) |
语句 p->m 被解释为 (p.operator->())->m。同样地,下面的实例演示了如何重载类成员访问运算符 ->。
1 |
|