目录
一:运算符重载的方法
-
形式:
-
对象 运算符 另一个值(可以不是对象,可以无)被解释为:对象.operator运算符(另一个值)
-
运算符被重载后,原来用于其他数据类型上的功能仍然被保留(重载),系统根据重载函数的规则匹配
-
例:复数的相加
二:运算符重载的规则:
-
只能对已有运算符进行重载,不能定义新运算符
-
不能重载的运算符只有五个:
-
不能改变操作对象的个数
-
不能改变优先级
-
不能改变结合性
-
不允许带默认参数
-
重载运算符的两侧至少有一个是类对象
-
=和&系统做了重载,=是对应内存拷贝,&是取地址
三:重载=运算符、重载构造函数实现含动态内存申请的赋值、复制
1.重载=的体外实现
class test{
private:
int a;
int b;
char *c;
public:
...
test &test::operator=(const test &t); //重载=的声明
}
//重载=的体外实现
test &test::operator=(const test &t)
{
a = t.a;
b = t.b;
delete[]c; //释放原空间
c = new char[strlen(t.c) + 1]; //申请新空间
strcpy(c, t.c);
return *this; //返回对象自身
}
Q:返回类型test &,为什么不能是test?
A:t2 = t1 希望理解为 t2.opetator=(t1),即this指针指向t2,而=的语意希望执行后t2被改变,因此返回test &
另一个例子:complex operator+(complex &b);
c1 + c2 理解为 c1.operator(t2),+的语意不能改变c1,因此+应该返回临时对象,所以返回值是 complex 而不是 complex &
2.复制构造函数的体外实现:
test::test(const test &s)
{
a = s.a;
b = s.b;
c = new char[strlen(s.c) + 1]; //申请新空间
strcpy(c, s.c);
}
四:运算符重载作为类成员函数和友员函数
- 因为要访问类的成员,所以需要定义为友员
- 运算符的同一种重载实现,友员/成员只能选一个
- 用全局普通函数也能实现运算符重载,但因为只能访问public对象,或通过类的公有成员函数访问private部分,因此效率低,一般不用
成员函数与友员函数的区别:
对单目运算符:
- 成员函数是空参数
- 友元函数是一个参数(必须是对象)
对双目运算符:
- 成员函数是一个参数(可不是对象)
对象(this) 双目运算符 参数- 友元函数是两个参数(一个必须是对象,另一个可不是)
第一个参数 双目运算符 第二个参数- 对两个都是对象的情况:没区别
- 对一个是对象的情况:
- 建议对单目运算符采用成员函数方式,双目运算符采用友元函数方式
- C++规定,某些运算符必须是成员函数形式(赋值=、下标[]、函数()),某些运算符必须是友元函数形式(流插入)
五:例子
1.重载++
Complex& Complex::operator++() //后缀
{
real++;
return this;
}
Complex Complex::operator++(int) //后缀
{
Complex c1(*this); //复制构造函数,用对象自身初始化c1
real++;
return c1;
}
2.重载流插入/流提取运算符
istream& operator>>(istream &in, Complex &a)
{
in >> a.real >> a.imag;
return in;
}
ostream& operator<<(ostream &out, Complex &a)
{
out << a.real;
if (a.imag >= 0)
out << '+';
out << a.imag << 'i';
return out;
}
六:不同类型数据间的转换
(一)用转换构造函数进行类型转换
- 只能带一个参数,非该类的数据类型,将该参数转换为对应的对象
- 系统无缺省定义,根据需要自行定义并使用
1.将double转换为Complex
class Complex{
...
public
...
Complex(double r) { real = r; imag = 0; }
...
}
2.整数n表示当天的秒,转换为Time对象
Time::Time(int n)
{
hour = n / 3600;
minute = n % 3600 / 60;
sec = n % 60;
}
(二)用类型转换函数进行类型转换
- 返回类型不是缺省的int,由类型名决定,无参数
- 只能是成员函数形式
- 在需要类型转换的地方被系统自动地隐式调用
Time::operator int()
{
return hour * 3600 + minute * 60 + sec;
}