跳到主要内容

C++ 编程中的增量 ++ 和减量 -- 运算符重载

提示
  1. 增量和减量运算符重载:在C++中,可以重载增量(++)和减量(--)运算符,使其适用于对象,以增加或减少对象的数据成员值。
  2. 前缀与后缀形式:这些运算符可以以前缀(++obj)或后缀(obj++)形式重载,区别在于它们的实现和返回值。
  3. 适用性和灵活性:除了增量和减量运算符,其他一元运算符(如 !, ~)也可以以类似方式重载,提高代码的适用性和灵活性。

要理解这个例子,您应该具备以下 C++ 编程 主题的知识:

在本教程中,我们将以最佳方式重载增量 ++ 和减量 -- 运算符,即如果对对象操作 ++ 运算符,则增加数据成员的值 1,如果使用 -- 运算符,则减少数据成员的值 1。

示例 1:前缀 ++ 增量运算符重载,无返回类型

#include <iostream>
using namespace std;

class Check
{
private:
int i;
public:
Check(): i(0) { }
void operator ++()
{ ++i; }
void Display()
{ cout << "i=" << i << endl; }
};

int main()
{
Check obj;

// 显示对象 obj 的数据成员 i 的值
obj.Display();

// 调用运算符函数 void operator ++( )
++obj;

// 再次显示对象 obj 的数据成员 i 的值
obj.Display();

return 0;
}

输出

i=0
i=1

最初,当声明对象 obj 时,对象 obj 的数据成员 i 的值为 0(构造函数将 i 初始化为 0)。

当对 obj 操作 ++ 运算符时,将调用运算符函数 void operator++( ),它将数据成员 i 的值增加到 1。

这个程序并不完整,因为你不能使用以下代码:

obj1 = ++obj;

这是因为上面程序中的运算符函数的返回类型为 void。

以下是上述程序的小修改,以便您可以使用代码 obj1 = ++obj

示例 2:带返回类型的前缀增量 ++ 运算符重载

#include <iostream>
using namespace std;

class Check
{
private:
int i;
public:
Check(): i(0) { }

// 返回类型为 Check
Check operator ++()
{
Check temp;
++i;
temp.i = i;

return temp;
}

void Display()
{ cout << "i = " << i << endl; }
};

int main()
{
Check obj, obj1;
obj.Display();
obj1.Display();

obj1 = ++obj;

obj.Display();
obj1.Display();

return 0;
}

输出

i = 0
i = 0
i = 1
i = 1

这个程序与上一个类似。

唯一的区别是,这种情况下运算符函数的返回类型为 Check,这允许使用 ++obj; obj1 = ++obj; 两种代码。这是因为,从运算符函数返回的 temp 被存储在对象 obj 中。

由于运算符函数的返回类型为 Check,您也可以将 obj 的值分配给另一个对象。

请注意,不需要重载 =(赋值运算符),因为这个运算符已经在 C++ 库中被重载了。

示例 3:后缀增量 ++ 运算符重载

到目前为止,只有当它以前缀形式使用时,增量运算符的重载才成立。

这是上面程序的修改,使其既适用于前缀形式,也适用于后缀形式。

#include <iostream>
using namespace std;

class Check
{
private:
int i;
public:
Check(): i(0) { }
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;
}

输出

i = 0
i = 0
i = 1
i = 1
i = 2
i = 1

当重载增量运算符为前缀形式时,会调用 Check operator ++ (),但是当重载增量运算符为后缀形式时,会调用 Check operator ++ (int)

注意,括号内的 int。这个 int 向编译器提供信息,表明它是运算符的后缀版本。

不要混淆,这个 int 并不表示整数。

示例 4:递减 -- 运算符的重载

递减运算符可以像递增运算符一样被重载。

#include <iostream>
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;
}

输出

i = 3
i = 3
i = 2
i = 2
i = 1
i = 2

同样,像 !, ~ 等一元运算符也可以以类似方式重载。