1 C++中++和--操作符的重载
2 C++中[][]操作符的重载
1,C++中++和--操作符的重载
在C++中操作符++和--的重载有一定的技巧性,原因是++(或--)可以置于对象前,或者是对象后,
如:class a;
a++;
a--;
这两种情况要分别编写不同的重载函数, 我们以TestCase类为例,来说明++和--操作符的重载函数的实现
声明一个最简单的TestCase类(只含有一个int型的私有成员)
//TestCase.h
#ifndef TESTCASE_H
#define TESTCASE_H
#include <iostream>
using namespace std;
class TestCase
{
public:
TestCase( int m);
int GetxValue() const;
private:
int x;
};
#endif
//TestCase.cpp
#include "TestCase.h"
TestCase::TestCase( int m) : x( m )
{
}
int TestCase::GetxValue() const
{
return x;
}
为了便于输出结果,我们对TestCase类重载输入输出操作符>>和<<:
在TestCase类中声明:
class TestCase
{
public:
.........
friend istream& operator >> ( TestCase& TC);
friend ostream& operator << ( TestCase& TC);
.........
private:
.........
};
在TestCase.cpp中实现这些函数如下:
istream& operator >> ( istream& istr, TestCase& TC)
{
istr >> TC.x;
return istr;
}
ostream& operator << ( ostream& ostr, TestCase& TC)
{
ostr << TC.x;
return ostr;
}
为了使TestCase类能够直接使用++和--操作符,我们在TestCase类中加入重载成员函数:
TestCase& operator ++ (); //前置版本
TestCase& operator -- ();
在TestCase.cpp中实现这两个函数如下:
TestCase& TestCase::operator ++ ()
{
++x;
return *this;
}
TestCase& TestCase::operator -- ()
{
--x;
return *this;
}
注意:以上只是TestCase类++/--操作符的前置版本:也就是++TestCase、--TestCase
++TestCase实际上就是调用TestCase.operator ++ (),对于--操作符同理。
为了使用TestCase++,和TestCase--,我们需要在类中声明这两个操作符的后置版本:
TestCase operator ++ (int);
TestCase operator -- (int);//后置版本
后置版本的实现比起前置版本要稍微复杂一点,原因是后置版本不仅要实现自加(自减),还需要实现与C++内建的
类型拥有同样的功能,即把TestCase对象TC的后置自加:TC++(自减TC--)版本在程序中参与运算时,时先让TC参与
运算,然后再对TC自加(自减)。
例如:TestCase TC(5);
cout << TC++ ; //输出5
cout << TC; //输出6
在TestCase.cpp中实现这两个函数如下:
TestCase TestCase::operator ++ (int)
{
TestCase Temp; //声明一个临时对象,保存调用 TestCase::operator ++ (int)函数的 TestCase对象
Temp.x = x++; //拷贝
return Temp;
}
我们可以做如下分析:
对于语句: cout << TC++ ;
可以看作: cout << TC.operator ++ (int) ;
TC调用自己的成员函数 operator ++ (int) 返回原来TC对象的拷贝,然后改变TC.x的值
实际上 cout << Temp;
至此,实现了内建类型的所有相同的功能。
同理,TestCase::operator -- (int)函数的实现版本如下:
TestCase TestCase::operator -- (int)
{
TestCase Temp;
Temp.x = x--;
return Temp;
}
注意,这里并不需要给出参数名,因为它没有被用到操作符的定义中,额外的整型参数对于后置操作符
的用户是透明的,编译器为他们提供了缺省的值,因而该参数可以被忽略,这就是参数没有被命名的
原因。
对于后置操作符的显示调用要求为第二个整型参数提供一个实际的值,对于我们的TestCase类,如果这个
参数没有在重载操作符的定义中用到,为以下显示调用操作符函数而指定的参数将被忽略。
TestCase. operator ++( 1024 ); //1024将被忽略
重载的++和--操作符也可以被声明为友元函数,例如在TestCase类中我们可以采用如下方式声明重载操作符
函数:
class TestCase
{
public:
.........
friend TestCase& operator ++ ( TestCase& TC); //前置
friend TestCase& operator -- ( TestCase& TC);
friend TestCase operator ++ ( TestCase& TC, int ); //后置
friend TestCase operator -- ( TestCase& TC, int );
.........
private:
.........
};
在TestCase.cpp中实现如下:
TestCase& operator ++ ( TestCase& TC)
{
++TC.x;
return TC;
}
TestCase& operator -- ( TestCase& TC)
{
--TC.x;
return TC;
}
TestCase operator ++ ( TestCase& TC, int )
{
TestCase Temp; //同理
Temp.x = TC.x++;
return Temp;
}
TestCase operator -- ( TestCase& TC, int )
{
TestCase Temp; //同理
Temp.x = TC.x--;
return Temp;
}
2 , C++中[][]操作符的重载
我们假设有一个Matrix类用来封装矩阵,并希望用[][]来取得矩阵对应位置的元素值。分析一下m.[a][b],可以看做是m.operator [a].operator [b]。所以要让第一个[]返回一个也重载了[]的辅助类,再把a传到那个辅助类中,想办法在后一个类的[]中实现对应元素的返回。代码如下(忽略了其他成员函数和越界检查):
class assis//辅助类
{
public:
int operator [](int index)
{
index2=index-1;
return pdata[index1*ncol+index2];
};
int * pData;
int index1,index2;
int ncol,nrow;
};
class Matrix//矩阵类
{
public:
...//其他成员函数
assis operator [](int index)
{
assis ret;
ret.pData=pData;
ret.ncol=ncol;
ret.nrow=nrow;
ret.index1=index-1;
return ret;
};
private:
int * pData;
int nrow,ncol;
...//其他成员变量
};
参考书:《C++ Primer 3rd Edition》