operator
关键字声明一个函数,该函数指定应用于类的实例时的运算符。 这将为运算符提供多个含义,或者将“重载”它。 编译器通过检查其操作数类型来区分运算符不同的含义。
运算符重载的一般规则
以下规则约束如何实现重载运算符,但是他不是用于new
和delete
:
- 不能定义新运算符
- 将运算符应用于内置数据类型时,不能重新定义其含义
- 重载运算符必须是非静态类成员函数获取全局函数。
- 需要访问私有或者收保护的类成员的全局函数必须声明为该类的友元
- 全局函数必须至少采用一个类类型或者枚举类型的自变量,或者作为对类类型或枚举类型的引用的自变量。 例如:
// rules_for_operator_overloading.cpp
class Point
{
public:
Point operator<( Point & ); // Declare a member operator
// overload.
// Declare addition operators.
friend Point operator+( Point&, int );
friend Point operator+( int, Point& );
};
int main()
{
}
- 运算符遵循它们通常用于内置类型时指定的操作数的优先级、分组和数量。
- 声明为成员函数的一元运算符将不采用自变量;如果声明为全局函数,它们将采用一个自变量
- 声明为成员函数的二元运算符将采用一个自变量;如果声明为全局函数,它们将采用两个自变量
- 如果运算符可用作一元运算符或二元运算符 (& 、 * 、 + 和 -) ,则可以单独重载每个使用。
- 重载运算符不能有默认自变量
- 派生类继承除赋值(运算符=)之外的所有重载运算符
- 成员函数重载运算符的第一个自变量始终属于针对其调用运算符的对象的类类型(从中声明运算符的类或派生自该类的类)。 没有为第一个参数提供转换。
重载=
赋值运算符 (=) 严格地说是二元运算符。 其声明与任何其他二元运算符的相同,但有以下例外:
- 它必须是非静态成员函数。 不能将 operator = 声明为非成员函数。
- 它不由派生类继承。
- 如果类类型不存在,则编译器会为类类型生成默认的 operator = 函数。
class Point
{
public:
int _x, _y;
// Right side of copy assignment is the argument.
Point& operator=(const Point&);
};
// Define copy assignment operator.
Point& Point::operator=(const Point& otherPoint)
{
_x = otherPoint._x;
_y = otherPoint._y;
// Assignment operator returns left side of assignment.
return *this;
}
int main()
{
Point pt1, pt2;
pt1 = pt2;
}
重载函数调用
使用括号调用的函数调用运算符是二元运算符。
// function_call.cpp
class Point
{
public:
Point() {
_x = _y = 0; }
Point &operator()( int dx, int dy )
{
_x += dx; _y += dy; return *this; }
private:
int _x, _y;
};
int main()
{
Point pt;
pt( 3, 2 );
}
也可以使用指向函数的指针(而非该函数本身)重载函数调用运算符。
typedef void(*ptf)();
void func()
{
}
struct S
{
operator ptf()
{
return func;
}
};
int main()
{
S s;
s();//operates as s.operator ptf()()
}
重载下标访问
下标运算符 ([]) (如函数调用运算符)被视为二元运算符。 下标运算符必须是采用单个参数的非静态成员函数。 此自变量可以是任何类型,并指定所需的数组下标。
// subscripting.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class IntVector {
public:
IntVector( int cElements );
~IntVector() {
delete [] _iElements; }
int& operator[](int nSubscript);
private:
int *_iElements;
int _iUpperBound;
};
// Construct an IntVector.
IntVector::IntVector( int cElements ) {
_iElements = new int[cElements];
_iUpperBound = cElements;
}
// Subscript operator for IntVector.
int& IntVector::operator[](int nSubscript) {
static int iErr = -1;
if( nSubscript >= 0 && nSubscript < _iUpperBound )
return _iElements[nSubscript];
else {
clog << "Array bounds violation." << endl;
return iErr;
}
}
// Test the IntVector class.
int main() {
IntVector v( 10 );
int i;
for( i = 0; i <= 10; ++i )
v[i] = i;
v[3] = v[9];
for ( i = 0; i <= 10; ++i )
cout << "Element: [" << i << "] = " << v[i] << endl;
}