在进行对象之间的运算时,程序会调用与运算符相对应的函数进行处理,所以运算符重载有两种方式:成员函数和友元函数。成员函数的形式比较简单,就是在类里面定义了一个与操作符相关的函数。友元函数因为没有this指针,所以形参会多一个。
以MyString类为列
#ifndef _MYSTRING_H_
#define _MYSTRING_H_
#include <iostream>
using namespace std;
class MyString
{
private:
int length;
char *data;
public:
MyString();
MyString(char *str);
MyString(int len,char ch);
MyString(const MyString &s);
~MyString();
friend ostream &operator <<(ostream &out,const MyString &s);
friend istream &operator >>(istream &in, MyString &s);
void operator =(char *str);
MyString &operator =(const MyString &s);
char &operator [](unsigned int index);
bool operator ==(char *str);
bool operator ==(const MyString &s);
bool operator !=(char *str);
bool operator !=(const MyString &s);
MyString operator +(const MyString &s);
MyString operator +(char *str);
MyString &operator +=(char *str);
};
#endif
#include "MyString.h"
#include <iostream>
#include <cstring>
using namespace std;
MyString::MyString()
{
length = 0;
data = NULL;
}
MyString::MyString(char *str)
{
length = strlen(str);
data = new char[length + 1];
strcpy(data,str);
data[length] = '\0';
}
MyString::MyString(int len,char ch)
{
length = len;
data = new char[length + 1];
for(int i = 0;i < length;i ++)
{
data[i] = ch;
}
data[length] = '\0';
}
MyString::MyString(const MyString &s)
{
length = s.length;
data = new char[length + 1];
strcpy(data,s.data);
data[length] = '\0';
}
MyString::~MyString()
{
if(data != NULL)
{
delete[]data;
data = NULL;
}
}
ostream &operator <<(ostream &out,const MyString &s)
{
out << s.data;
return out;
}
istream &operator >>(istream &in, MyString &s)
{
s.length = sizeof(in);
if(s.data != NULL)
{
delete[]s.data;
}
s.data = new char[s.length];
in >> s.data;
s.data[s.length - 1] = '\0';
return in;
}
void MyString::operator =(char *str)
{
length = strlen(str);
if(data != NULL)
{
delete[]data;
}
data = new char[length + 1];
strcpy(data,str);
data[length] = '\0';
}
MyString &MyString::operator =(const MyString &s)
{
length = s.length;
if(data != NULL)
{
delete[]data;
}
data = new char[length + 1];
strcpy(data,s.data);
data[length] = '\0';
return *this;
}
char &MyString::operator [](unsigned int index)
{
return data[index];
}
bool MyString::operator ==(char *str)
{
return (!strcmp(data,str));
}
bool MyString::operator ==(const MyString &s)
{
return (!strcmp(data,s.data));
}
bool MyString::operator !=(char *str)
{
return strcmp(data,str);
}
bool MyString::operator !=(const MyString &s)
{
return strcmp(data,s.data);
}
MyString MyString::operator +(const MyString &s)
{
char temp[length + s.length + 1];
strcpy(temp,data);
strcat(temp,s.data);
temp[length + s.length ] = '\0';
return MyString(temp);
}
MyString MyString::operator +(char *str)
{
char temp[length + strlen(str) + 1];
strcpy(temp,data);
strcat(temp,str);
temp[length + strlen(str)] = '\0';
return MyString(temp);
}
MyString &MyString::operator +=(char*str)
{
char *temp = data;
length = length + strlen(str);
data = new char(length + 1);
strcpy(data,temp);
strcat(data,str);
data[length] = '\0';
delete[]temp;
return *this;
}
MyString &MyString::operator +=(const MyString s)
{
char *temp = data;
length = length + s.length;
data = new char(length + 1);
strcpy(data,temp);
delete[]temp;
return *this;
}
注:
- 除了类属关系运算符”.“、成员指针运算符”.*“、作用域运算符”::“、sizeof运算符和三目运算符”?:“以外,C++中的所有运算符都可以重载。
- 重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
- 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
- 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
- 运算符重载不能改变该运算符用于内部类型对象的含义。它只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。
- 运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。