C++提供了运算符重载的功能,对于我们自定义的类,使用运算符重载能够简化对像的操作。比如C++的string其实就使用了运算符重载功能,因此我们才能对其使用+
,==
等操作。
不可重载的运算符:.
,::
,.*
,:?
,sizeof
。其余运算符都是可重载的。但是,有些运算符的重载我们也很少使用,比如重载new
,delete
运算符,这可能给使用者造成困惑。
Java完全没有运算符重载,但是其类库却无比庞大,而且非常易用。可见,运算符重载并不是非用不可。但是适当的使用运算符重载确实能够简化代码,这里我们只介绍几个简单的运算符重载。
下面例子重载了=
操作符,允许直接将字符串字面值赋值给我们自定义的mystring
类。
#include <iostream>
#include <cstring>
using namespace std;
class mystring
{
private:
char *s;
public:
mystring()
{
this->s = new char[1024];
}
mystring(const mystring &it)
{
this->s = new char[1024];
strcpy(this->s, it.s);
}
void operator =(const char *s)
{
strcpy(this->s, s);
}
void print()
{
cout << this->s << endl;
}
~mystring()
{
delete[] this->s;
}
};
int main()
{
mystring s1;
s1 = "hello, world!";
mystring s2 = s1;
s2.print();
return 0;
}
这里重载操作符的写法就是:void operator =(const char *s){}
,和定义一个函数差不多operator =
其实就相当于函数名。
注意:mystring s2 = s1
执行的其实是拷贝构造函数,定义为mystring(const mystring &it){}
,这里=
原来的意义并没有改变,因为其参数类型是mystring &
而不是const char *
。实际上操作符重载的函数也是可以重载的。
下面例子重载了+
运算符。实现了mystring之间相加,mystring和字符串字面值相加,字符串字面值和mystring相加三种功能。
#include <iostream>
#include <cstring>
using namespace std;
class mystring
{
private:
char *s;
public:
mystring()
{
this->s = new char[1024];
}
mystring(const char *s)
{
this->s = new char[1024];
strcpy(this->s, s);
}
mystring(const mystring &it)
{
this->s = new char[1024];
strcpy(this->s, it.s);
}
mystring operator +(mystring &it)
{
char buf[1024];
strcpy(buf, this->s);
strcat(buf, it.s);
return buf;
}
mystring operator +(const char *s)
{
char buf[1024];
strcpy(buf, this->s);
strcat(buf, s);
return buf;
}
void print()
{
cout << this->s << endl;
}
~mystring()
{
delete[] this->s;
}
friend mystring operator +(const char *s, const mystring &m);
};
mystring operator +(const char *s, const mystring &m)
{
char buf[1024];
strcpy(buf, m.s);
strcat(buf, s);
return buf;
}
int main()
{
mystring s1("hello");
mystring s2("world");
mystring s3 = s1 + s2;
s3.print();
mystring s4 = s1 + "aaa";
s4.print();
mystring s5 = "bbb" + s2;
s5.print();
return 0;
}
注意mystring operator +(const char *s, const mystring &m)
,这个是定义在类的外面的,但是它需要访问类内部的成员,因此类中声明了该函数为友元。
下面例子重载了==
操作符。
#include <iostream>
#include <cstring>
using namespace std;
class mystring
{
private:
char *s;
public:
mystring()
{
this->s = new char[1024];
}
mystring(const char *s)
{
this->s = new char[1024];
strcpy(this->s, s);
}
mystring(const mystring &it)
{
this->s = new char[1024];
strcpy(this->s, it.s);
}
bool operator ==(const mystring &it)
{
if(strcmp(this->s, it.s) == 0)
{
return true;
}
else
{
return false;
}
}
void print()
{
cout << this->s << endl;
}
~mystring()
{
delete[] this->s;
}
friend bool operator ==(const mystring &s1, const mystring &s2);
};
bool operator ==(const mystring &s1, const mystring &s2)
{
if(strcmp(s1.s, s2.s) == 0)
{
return true;
}
else
{
return false;
}
}
int main()
{
mystring s1("hello");
mystring s2("hello");
if(s1 == s2)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
return 0;
}
和+
的写法基本是相同的,注意重载==
要求返回值是bool类型,这符合==
的语意。
其余的操作符重载这里就不介绍了。