操作符重载其实和函数没什区别,要记住的是: 重载运算操作符的参数列表比普通函数少一个( 对于成员操作符,隐式的this指针被用作隐式的第一个参数)。表达式中最左边的对象是调用操作符重载函数的对象,而最右边的那个将被作为参数传送。
形式为:
返回类型 operator 操作符 (参数列表){}
总结提要:
1.重载运算符:
对于成员操作符,隐式的this指针被用作隐式的第一个参数。
2.C++要求,=,[],(),->必须被定义为成员操作符。
3.只有在C++预定义操作符集中的操作符才可以被重载。
eg:
int operator**();//error
4.对于内置的操作符,它的预定义意义不能被改变。也不能为内置的数据类型定义其它的操作符。
eg:
int operator+(int,int);//error,不能为int重新定义内置的操作符
5.程序员只能为类类型或枚举类型的操作时定义重载操作符。
6.预定义的操作符优先级不能被改变。
7.操作符预定义的操作个数必须被保留
eg:
bool operator!(int,int);//error,一元的逻辑非不能有两个参数
8.重载后置运算符
< type > ClassName :: operator ++ ( int )
{
......
}
friend <type> operator ++(ClassName &,int);
9.重载operator[]下标运算符时建议返回引用类型,否则无法进行赋值操作
eg:
class A
{
public:
......
char& operator[](int index);
private:
char *str;
}
A a("hello");
a[1]='\a';//ok 如果重载为char operator[](int index); 则出错
10.重载函数调用操作符operator();
eg:
class MyInt
{
public:
int operator()(int abs);
};
int MyInt:: operator()(int abs)
{
return abs>=0?abs:-abs;
}
int main()
{
MyInt mi;
cout<<mi(-1)<<endl;//1
return 0;
}
下面给出一个仿C++string类的MyString类,该类重载了大部分常见的运算操作符。
MyString.h
#ifndef MyString_H
#define MyString_H
#include<iostream>
using namespace std;
class MyString
{
public:
MyString():_size(0),str(NULL){};
MyString(char *str);
MyString(MyString &cp);
char *c_str(){return str;}
ostream& print(ostream &os)
{
if(str)
{
os<<str;
}
return os;
}
MyString& operator=(char *str);
MyString& operator=(MyString &cp);
MyString& operator+=(char *rstr);
MyString& operator+=(MyString &cp);
bool operator==(MyString &other)const;
bool operator!=(MyString &other)const;
bool operator>(MyString &other)const;
bool operator<(MyString &other)const;
bool operator==(char *other)const;
bool operator!=(char *other)const;
bool operator>(char *other)const;
bool operator<(char *other)const;
~MyString(){ delete [] str;}
private:
int _size;
char *str;
static int length(char *str);
static void copy(char *&des,char *source);
static void constructor_init(MyString *ms,char *str);
static int compare(char *str1,char *str2);
};
#endif
MyString.cpp
#include"MyString.h"
//计算字符串的个数,不包括'\0';
int MyString::length(char *str)
{
int count=0;
while(str[count++]);
return count-1;
}
//复制字符串
void MyString::copy(char *&des,char *source)
{
int len=length(source);
des=new char[len+1];
int index=0;
while(source[index])
{
des[index]=source[index];
index++;
}
des[index]='\0';
}
//比较两字符串的大小
int MyString::compare(char *str1,char *str2)
{
int index=0;
while(str1[index]&&str2[index])
{
if(str1[index]!=str2[index])
{
return str1[index]-str2[index];
}
index++;
}
return (str1[index]=='\0'&&str2[index]=='\0')?0:(str1[index]=='\0'?-1:1);
/*
*等价于上面的语句
if(str1[index]=='\0'&&str2[index]=='\0')
{
return 0;
}
else
{
if(str1[index]=='\0')
{
return -1;
}
else
{
return 1;
}
}
*/
}
/*
*用来初始化构造函数,由于MyString(char *)和MyString(MyString &cp)有相同的
*部分,所以抽取出来,注意,这里的MyString *ms只能传递this指针,否则私有成员
*无法访问
*/
void MyString::constructor_init(MyString *ms,char *str)
{
if(str)
{
int len=length(str);
ms->_size=len;
copy(ms->str,str);
}
else
{
ms->_size=0;
ms->str=NULL;
}
}
MyString::MyString(char *str)
{
constructor_init(this,str);
}
MyString:: MyString(MyString &cp)
{
constructor_init(this,cp.c_str());
}
//重载字符串型的=运算符
MyString& MyString::operator=(char *str)
{
if(str)
{
if(this->str)
{
delete [] this->str;
}
copy(this->str,str);
this->_size=length(str);
}
return *this;
}
//重载MyString型的=运算符
MyString& MyString::operator=(MyString &cp)
{
operator=(cp.c_str());
return *this;
}
//重载字符串型的+=运算符
MyString& MyString::operator+=(char *rstr)
{
if(rstr)
{
int len=_size+length(rstr);
char *mstr=new char[len+1];
int index=0;
if(str)
{
while (str[index]) //把原字符串复制到mstr
{
mstr[index]=str[index];
index++;
}
}
int index1=0;
while (rstr[index1])//把rstr接到mstr的尾部
{
mstr[index]=rstr[index1];
index++;
index1++;
}
mstr[index]='\0';
*this=mstr;
_size=len;
}
return *this;
}
//重载MyString型的+=运算符
MyString& MyString::operator+=(MyString &cp)
{
operator+=(cp.c_str());
return *this;
}
//重载字符串型的==运算符
bool MyString::operator==(char *other)const
{
int len=length(other);
if(_size==len)
{
int index=0;
while((str[index]==other[index])&&other[index])
{
index++;
}
if(index==_size)
{
return true;
}
else
{
return false;
}
}
return false;
}
//重载字符串型的+=运算符
bool MyString::operator!=(char *other)const
{
if(operator==(other))
{
return false;
}
else
{
return true;
}
}
//重载字符串型的>运算符
bool MyString::operator>(char *other)const
{
return compare(str,other)>0?true:false;
}
//重载字符串型的<运算符
bool MyString::operator<(char *other)const
{
return compare(str,other)<0?true:false;
}
//重载MyString型的==运算符
bool MyString::operator==(MyString &other)const
{
return operator==(other.c_str());
}
//重载MyString型的!=运算符
bool MyString::operator!=(MyString &other)const
{
return operator!=(other.c_str());
}
//重载MyString型的>运算符
bool MyString::operator>(MyString &other)const
{
return operator>(other.c_str());
}
//重载MyString型的<运算符
bool MyString::operator<(MyString &other)const
{
return operator<(other.c_str());
}
main.cpp
#include<iostream>
using namespace std;
#include"MyString.h"
//重载输出流<<
ostream& operator<<(ostream &os,MyString &str)
{
str.print(os);
return os;
}
int main(void)
{
MyString str;//测试无参构造函数
MyString str1("hello");//测试字符串参构造函数
str+=str1; //测试MyString型+=
str+=" how "; //测试字符串型+=
MyString str2("are you");
MyString str3(str2);//测试MyString型构造函数
str+=str2;
cout<<str<<endl;//输出hello how are you
cout<<endl;
MyString str4("hello");
cout<<(str1==str4)<<endl;//1
cout<<(str1!=str4)<<endl;//0
cout<<(str1>str4)<<endl;//0
cout<<(str1<str4)<<endl;//0
cout<<endl;
cout<<(str1=="hello")<<endl;//1
cout<<(str1!="hello")<<endl;//0
cout<<(str1>"hello")<<endl;//0
cout<<(str1<"hello")<<endl;//0
cout<<endl;
MyString str5("helloa");
cout<<(str1==str5)<<endl;//0
cout<<(str1!=str5)<<endl;//1
cout<<(str1>str5)<<endl;//0
cout<<(str1<str5)<<endl;//1
cout<<endl;
cout<<(str1=="helloa")<<endl;//0
cout<<(str1!="helloa")<<endl;//1
cout<<(str1>"helloa")<<endl;//0
cout<<(str1<"helloa")<<endl;//1
cout<<endl;
MyString str6("helloa");
cout<<(str6==str1)<<endl;//0
cout<<(str6!=str1)<<endl;//1
cout<<(str6>str1)<<endl;//1
cout<<(str6<str1)<<endl;//0
cout<<endl;
MyString str7("nihao");
str1=str7;
cout<<str1<<endl;//输出nihao
str1="thanks";
cout<<str1<<endl;//输出thanks
return 0;
}
运行结果: