C++提供了运算符重载的功能,对于我们自定义的类,使用运算符重载能够简化对像的操作。举例来说,C++标准库的std::string
其实就使用了运算符重载功能,因此我们才能对其使用+
,==
等操作。C++中除了.
,::
,.*
,:?
,sizeof
,其余运算符都是可重载的,不过有些运算符的重载我们其实很少使用,比如重载new
,delete
运算符就非常罕见,这可能给使用者造成困惑。
运算符重载一直是个有巨大争议的特性,Java完全没有运算符重载,但是其类库却无比庞大而且非常易用,可见运算符重载也并不是非用不可。不过C++中适当的使用运算符重载确实能够简化代码,可见这个功能也有其存在意义。这里我们介绍几个简单的运算符重载。
运算符重载遵循以下规则:
下面例子重载了=
操作符,允许直接将字符串字面值赋值给我们自定义的mystring
类。
#include <cstring>
#include <iostream>
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() { std::cout << this->s << std::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 <cstring>
#include <iostream>
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() { std::cout << this->s << std::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 <cstring>
#include <iostream>
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() { std::cout << this->s << std::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) {
std::cout << "true" << std::endl;
} else {
std::cout << "false" << std::endl;
}
return 0;
}
和+
的写法基本是相同的,注意重载==
要求返回值是bool类型,这符合==
的语意。