c++操作符重载

时间:2021-02-27 17:47:59

c++操作符重载(翻译)

翻译自:http://www.cplusplus.com/doc/tutorial%20%20/classes2/


对于c++中基本的类型,我们可以采用如下方式进行操作:

int a, b, c;

a = b + c;

但是,对下面的操作就会产生编译错误,因为我们没有定义这个操作类型有“+”操作。

struct {

 string product;

 float price;

} a, b, c;

a = b + c;

 

但是,幸好有c++的操作符重载,我们可以设计实现上例中的操作。

下面是能够重载的操作符列表:

可重载的操作符

+    -    *    /    =    <    >    +=   -=   *=   /=   <<   >>

<<=  >>=  ==   !=   <=   >=   ++   --   %    &    ^    !    |

~    &=   ^=   |=   &&   ||   %=   []   ()   ,    ->*  ->   new

delete    new[]     delete[]

 

我们在类中使用操作函数去重载一个操作符,这个函数是一个以operator关键字后加需要重载的操作符(sign)为函数名称的普通函数,格式如下:

typeoperator sign (parameters){/*…*/}

 

下面是一个重载“+”操作符的例子,这个例子是创建一个存储双向vectors向量类,然后我们使用重载的“+”操作符直接相加两个类的对象a(3,1)和b(1,2)。两个向量相加的操作如下,两个x坐标相加获得x坐标结果,两个y坐标相加获得y坐标结果,因此最后结果为:(3+1,1+2) = (4,3)。

 

// vectors: overloading operators example

#include <iostream>

using namespace std;

 

class CVector {

 public:

   int x,y;

   CVector () {};

   CVector (int,int);

   CVector operator + (CVector);

};

 

CVector::CVector (int a, int b) {

  x =a;

  y =b;

}

 

CVector CVector::operator+ (CVector param){

 CVector temp;

 temp.x = x + param.x;

 temp.y = y + param.y;

 return (temp);

}

 

int main () {

 CVector a (3,1);

 CVector b (1,2);

 CVector c;

  c =a + b;

 cout << c.x << "," << c.y;

 return 0;

}

程序中的以下两句可能会让你感到迷惑:

CVector (int, int);            // function name CVector(constructor)

CVector operator+ (CVector);   // function returns a Cvecto

上边的是CVector类的构造函数,带两个int类型的参数,下面的是返回为Cvector类型的“+”操作符函数。

 

Cvector类的operator+函数是重载“+”操作符的一种方式。这个函数即可以用“+”操作符隐式调用也可以用函数名显示调用,如下两种方式:

c = a + b;

c = a.operator+(b);

这两种调用方式是等价的。

我们会发现类中有个空的结构体(没有参数),并且用空的模块定义:CVector () { };

这是必须要的,虽然我们显示的调用另一个结构体:CVector (int, int);

如果没有空的结构体,main中的CVector c;就会变的不合法。

 

无论如何,我还是要警告你,一个空的模块对于一个构造函数是不好的,因为它没有满足结构体最小的功能---初始化类中所有的成员变量。在上边的例子中,结构体中并没有初始化变量x和y。因此,更好的定义如下:

CVector () { x=0; y=0; };

同时,类中包含一个默认的拷贝构造函数(即使它们没定义),同时也包括一个默认的以类作为参数的“=”操作符函数。例子如下:

CVector d (2,3);

CVector e;

e = d;           // copy assignment operator

这个拷贝操作符函数唯一的默认的操作符函数,当然你可以重新定义其他的功能,例如拷贝某些类的成员或者增加初始化操作等。

 

重载操作符不要改变操作符的原有的数学或者通用的操作规则,例如不要重载operator+操作符来实现“-”的操作。

 

函数operator+的原型是很明显的,右操作符作为操作符成员函数的参数,其他的操作符可能就没那么明显了。下表是不同操作符函数声明一个总结:

表达式

操作符

成员函数

全局函数(友元函数)

@a

+ - * & ! ~ ++ --

A::operator@()

operator@(A)

a@

++ --

A::operator@(int)

operator@(A,int)

a@b

+ - * / % ^ & | < > == != <= >= << >> && || ,

A::operator@ (B)

operator@(A,B)

a@b

= += -= *= /= %= ^= &= |= <<= >>= []

A::operator@ (B)

-

a(b, ...)

()

A::operator() (B, C...)

-

a->x

->

A::operator->()

-

表中,a是类A的对象,b是类B的对象,c是类C的对象。

在表中,可以看出有两种方法可以重载一些类操作符:作为成员函数和最为全局函数。它们使用哪个的好处是不清楚的(视使用情景而定),但是提醒你的是,不是成员函数的函数----全局函数。如果是友元函数,可以访问此类的私有成员和保护成员。