一、重载例子:
class COperator
{
public:
int a;
int b;
public:
COperator (void);
COperator (COperator &op);
~COperator (void);
//操作符重载
COperator operator +(COperator &op);
friend COperator operator - (COperator &op1,COperator &op2);
COperator &operator ++ (int);
COperator operator ++();
};
#include ".\opartor.h"
#include
using namespace std;
COperator::COperator(void)
{
}
COperator::~COperator(void)
{
}
COperator::COperator(COperator &op)
{
this->a = op.a;
this->b = op.b;
cout << "COPY构造被调用"<
}
COperator COperator::operator +(COperator &op)
{
COperator temp;
temp.a = this->a + op.a;
temp.b = this->b + op.b;
cout << "重载加法被调用"<
return temp;
}
COperator operator -( COperator &op1,COperator &op2)
{
COperator temp;
temp.a = op1.a - op2.b;
temp.b = op1.b - op2.b;
cout << "友元重载减法被调用" <
return temp;
}
COperator COperator::operator ++()
{
COperator temp(*this);
(this->a)++;
(this->b)++;
cout << "右增量被调用" <
return temp;
}
COperator &COperator::operator ++(int)
{
cout << "左增量被调用" <
(this->a)++;
(this->b) ++;
return *this;
}
上述是一个重载的例子。应该说这几种重载包含了重载的各种类型。下述章节中会分类介绍。
三、可以重载的运算符
C++规定了五个不能重载的运算符“.、::、.*、.->*、?”其它运算符都是可以重载的。
下列运算符不允许重载:
.,.,::,?:
四、运算符重载格式
返回类型 operator 运算符号(参数说明)
例如上例中对加法的重载: COperator operator +(COperator &op);
C++中规定,运算符中参数说明是内部类型时,不能重载。运算符重载过程中不会改变改运算符的运算优先级。
五、运算符重载的参数
运算符重载的参数,往往是初学者难以掌握的。其实很简单:参加运算的所有变量都是运算符的参数。比如说加法重载过程中,有两个参与的变量:加数和被加数。那我们就我对它进行重载的过程中需要两个参数。
需要指出的增量运算符有两种形式,前增量(运算符在变量前面)和后增量。前增量我们可以把他看做只有一个参数,而后增量我们可以看为a++0。事实上他是两个参数。只是在运算过程中,第二个参数我们不用而已。
运算符的重载有两个方式,一种是做为成员函数,另一种是做为友无函数。前种C++默认省略第一个参数(事实上是对象本身),而后一种是所有的参数都要写全。比如对加法的重载:
成员方式为:COperator operator +(COperator &op);在调用的过程中我们可以理解为result = operator+(op)
友元方式为:friend COperator operator - (COperator &op1,COperator &op2);在调用的过程中我们可以理解为result = operator-(op1,op2);
注:上面的理解方式可以看出,除了在调用形式上不同,重载的运算符和普通的函数是等效的。
六、返回值
C++中没有对重载函数的返回值做太多的限制。为了使调用都能够理解你所重载的函数,不会产生二义性。一般来讲重载运算符的返回值会是该类的对象或是该类对象的引用。
在C++中所有函数(包括重载的运算符)在返回的过程中会构建一个返回类型的临时对象。当函数执行完之后,这个对象会消失。应该说它是C++中生命周期最短的变量。值得指出的是,系统构建这个临时对象的过程中会调用COPY构造函数。关于这一点笔都会在另一个话题中说明。
重载返回值是返回引用还是返回一个对象是由我们需要决定的。为了不让调用者曲解,如果在运算过程中改变了参与运算的变量的值往往我们返回引用,如果不改变的话我们返回对象。例如:在加法重载中,两个参与运算的变量都没有改变,所以我们就要返回一个新的对象,而不是两个对象中的一个。(不要返回一个局部引用,会出错的)。而在前增量运算的过程中,返回的是我们改变后的对象,这样直接返回引用就可以的。
重载运算符坚持4个“不能改变”。
不能改变运算符操作数的个数;
不能改变运算符原有的优先级;
不能改变运算符原有的结合性;
不能改变运算符原有的语法结构。
答:
第一个C不是函数名称,也不是构造函数,而是类名。C& 既是返回值类型,为返回一个类C的对象。
*this表示被调用的成员函数所在的对象,*this就是this所指向的对象,即当前对象。
#include
using namespace std;
class C
{
public:
char m_val;
C& operator =(char i);
};
C& C::operator =( char i )
{
m_val = 'a';
if( 'l' <= i && i <= 'm' || 'n' <= i && i <= 'h' || i == 'b' )
m_val=i;
return *this;
}
int main()
{
char d;
C f;
C *p;
d = getchar();
p = &f.operator =(d);
cout << p->m_val;
return 0;
}
任何一个函数第一个都是返回类型
这个返回类型是类引用。
运算符重载的意义是给符号“=”赋予了一个新的含义,不仅可以给普通变量赋值,还可以给类赋值
#include
#include
class string{
public:
//定义构造函数
string(char *s){
ptr=new char[strlen(s)+1];
strcpy(ptr,s);
}
//定义析构函数
~string(){
delete [] ptr;
}
//声明重载运算符=
string &operator =(const string &s);
//定义类成员函数
void print(){
cout<
private:
char *ptr;
};
//定义重载运算符
string &string::operator =(const string &s){
if(this==&s)
return *this;
delete ptr;
ptr=new char[strlen(s.ptr)+1];
strcpy(ptr,s.ptr);
return *this;
}
所谓重载运算符就是根据你自己生成的类的需要来重新解释运算符的功能
比如在Integer中,运算符=的功能是把一个整数类型的右值赋值给同类型的左值;但是如果继续用这个解释,就无法在新的类中正常运作。因此需要重新定义。
在这个实例中,等号运算符的功能是以一个string类型变量的引用为参数返回一个string类型的指针。如果当前指针已经指向参数s,那么直接返回当前指针;否则,创建一个新对象,并且通过strcpy函数将s的赋值给它,之后返回该对象的指针。