【c++】重载运算符|赋值运算符

运算符重载

• 对已有的运算符赋予多重的含义
• 使同一运算符作用于不同类型的数据时 -> 不同类型的行为
• 运算符重载的实质是函数重载
运算符重载为普通函数
重载为普通函数时, 参数个数为运算符目数

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;
} 

重载赋值运算符

重载运算符两边的类型可以不匹配

  • 把一个int类型变量赋值给一个complex对象
  • 把一个char*类型的字符串赋值给一个字符串对象
    需要重载赋值运算符‘=’
    赋值运算符‘=’只能重载为成员函数,不能重载为普通函数
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类编写 复制构造函数时,会面临和 ‘=’ 同样的问题, 用同样的方法处理

你可能感兴趣的:(cpp)