• 对已有的运算符赋予多重的含义
• 使同一运算符作用于不同类型的数据时 -> 不同类型的行为
• 运算符重载的实质是函数重载
运算符重载为普通函数
重载为普通函数时, 参数个数为运算符目数
class Complex {
public:
Complex( double r = 0.0, double i= 0.0 ){
real = r;
imaginary = i;
}
double real; // real part
double imaginary; // imaginary part
};
Complex operator+ (const Complex & a, const Complex & b)
{
return Complex( a.real+b.real, a.imaginary+b.imaginary);
} // “类名(参数表)” 就代表一个对象
Complex a(1,2), b(2,3), c;
c = a + b;
运算符重载为成员函数
重载为成员函数时, 参数个数为运算符目数减一
class Complex {
public:
Complex( double r= 0.0, double m = 0.0 ):
real(r), imaginary(m) { } // constructor
Complex operator+ ( const Complex & ); // addition
Complex operator- ( const Complex & ); // subtraction
private:
double real; // real part
double imaginary; // imaginary part
};
// Overloaded addition operator
Complex Complex::operator+(const Complex & operand2) {
return Complex( real + operand2.real, imaginary + operand2.imaginary );
}
// Overloaded subtraction operator
Complex Complex::operator- (const Complex & operand2){
return Complex( real - operand2.real, imaginary - operand2.imaginary );
}
int main(){
Complex x, y(4.3, 8.2), z(3.3, 1.1);
x = y + z;
x = y - z;
return 0;
}
重载运算符两边的类型可以不匹配
class String {
private:
char * str;
public:
String () : str(NULL) { } //构造函数, 初始化str为NULL
const char * c_str() { return str; }
char * operator = (const char * s);
~String();
};
//重载 ‘=’ obj = “hello”能够成立
char * String::operator = (const char * s){
if(str) delete [] str;
if(s) { //s不为NULL才会执行拷贝
str = new char[strlen(s)+1];
strcpy(str, s);
}
else
str = NULL;
return str;
}
String::~String( ) {
if(str) delete [] str;
};
int main(){
String s;
s = “Good Luck,” ;
cout << s.c_str() << endl;
// String s2 = “hello!”; //这条语句要是不注释掉就会出错
//调用的是构造函数,但是没有参数为char*的构造函数
s = "Shenzhou 8!";
cout << s.c_str() << endl;
return 0;
}
浅复制/浅拷贝
• 执行逐个字节的复制工作
注意要避免使用浅拷贝,因为浅拷贝实际上是指向了同一块内存空间,可能会面临重复释放内存空间的问题
深复制/深拷贝
• 将一个对象中指针变量指向的内容, 复制到另一个对象中指针成员对象指向的地方
MyString s;
s = “Hello”;
s = s;
//这样是不可以的,可能已经把这块地方的内容删掉了,但是又要用这个地方的内容去赋值给另一个地方
//正确写法
String & String::operator = (const String & s){
if(str == s.str) return * this;
if(str) delete [] str;
if(s.str) { //s.str不为NULL才会执行拷贝
str = new char[strlen(s.str)+1];
strcpy( str,s.str);
}
else
str = NULL;
return * this;
}
对 operator = 返回值类型的讨论
void?不好, a = b = c;//等价于a.operator=(b.operator=c);
String?可以但是不好,尽量用String &,运算符重载时, 好的风格是尽量保留运算符原本的特性,如果(a = b) = c;//会修改a的值
(a.operator=(b)).operator=©;//只有是a的引用才能作为下一个的对象
为 String类编写 复制构造函数时,会面临和 ‘=’ 同样的问题, 用同样的方法处理