运算符重载
- 对已有的运算符赋予多重的含义
- 使同一运算符作用于不同类型的数据时 ⇒ \Rightarrow ⇒ 不同类型的行为
目的 : 扩展cpp中提供的运算符的适用范围,以用于类所表示的抽象数据类型
在程序编译时:
- 把含运算符的表达式
⇒
\Rightarrow
⇒ 对
运算符函数
的调用 - 把运算符的操作数
⇒
\Rightarrow
⇒ 运算符函数的
参数
- 运算符被多次重载时,根据
实参的类型
决定调用哪个运算符函数 - 运算符可以被重载成
普通函数
- 也可以被重载成
类的成员函数
重载为普通函数时,参数个数为运算符目数
Complex operator+(const Complex & a,const Complex & b){
return Complex(a.real+b.real,a.imaginary+b.imaginary);
}//“类名(参数表)”就代表一个对象
重载为成员函数时,参数个数为运算符目数减一
Complex operator+(const Complex&);// addition
赋值运算符重载
赋值运算符两边的类型可以不匹配
赋值运算符"="只能重载为成员函数
浅拷贝和深拷贝的概念
浅拷贝:将指针指向所需拷贝的内容所在的内存空间
深拷贝:将所需拷贝的内容复制到指定内存空间,并将指针指向该内存
深拷贝程序实现:
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]; //这里的+1 是为存储'\0'
strcpy(str,s.str);
}
else str = NULL;
return *this;
注意:
1. 不要设置返回值为 void
2. 复制构造函数面临’='中的浅拷贝问题
字符串拷贝 strcpy(new,old)
内存拷贝 memcpy(new,old,sizeof(type)*size)
流运算符重载
istream & operator >> (istream&is,Complex&c){
string s;
is >>s; //将"a+bi"作为字符串读入,"a+bi"中间不能有空格
int pos=s.find("+",0);
string sTmp=s.substr(0,pos); //分离出代表实部的字符串
c.real=atof(sTmp.c str());
//atof库函数能将const char*指针指向的内容转
sTmp=s.substr(pos+1,s.length()-pos-2); //分离出代表虚部的字符串
c.imag=atof(sTmp.c_str());
return is;
}
ostream&operator<<(ostream&os,const Complex cc){
os<<c.real <<"+"<<c.imag<<"i"; //以"a+bi"的形式输出
return os;
}
自加自减运算符重载
前置运算符作为一元运算符重载
- 重载为成员函数:
T operator++();
T operator–(); - 重载为全局函数:
T operator++(T);
T operator–(T);
后置运算符作为二元运算符重载,多写一个参数,具体无意义,只为区别于前置运算符
- 重载为成员函数:
T operator + + (int);
T operator - - (int); - 重载为全局函数:
T operator + + (T,int);
T operator - - (T,int);
重载类型强制转换运算符
operator int() { return n; }
int作为一个类型强制转换运算符被重载,
Demo s;
int(s); //等效于s.int();
类型强制转换运算符重载时,
- 不能写返回值类型
- 实际上其返回值类型 = 类型强制转换运算符代表的类型
运算符重载注意事项
- cpp不允许定义新的运算符
- 重载后运算符的含义应该符合日常习惯
- complex_a + complex_b
- word_a > word_b
- date_b = date_a + n
- 运算符重载不改变运算符的优先级
- 以下运算符不能被重载 :
.
,.*
,::
,?:
,sizeof
- 重载运算符
()
,[]
,->
或者赋值运算符=
时,重载函数必须声明为类的成员函数