程序设计与算法(三)C++面向对象程序设计-郭炜 第四周
基本概念
- 预定义的运算符只能用于基本数据类型(整型、实型、字符型、逻辑型)
- 两个对象之间也想直接运算
- 对已有的运算符赋予多重含义,扩展其适用范围
- 运算符重载实质是函数重载,可为普通函数,亦可成员函数
- 含运算符的表达式转换为对运算符函数的调用,操作数称为参数
- 重载为成员函数,参数个数为运算符目数减一;重载为普通函数,参数个数为运算符目数
- 返回值最好是引用
程序举例
#include <iostream>
using namespace std;
class complex {
public:
double real;
double imag;
complex operator + (const complex& z) {
return complex(real + z.real, imag + z.imag);
}
complex(double r = 0.0, double i = 0.0):real(r), imag(i) {}
complex(const complex& z) {
real = z.real;
imag = z.imag;
cout << "copy constructor" << endl;
}
void print() {
cout << real << " + " << imag << 'i' << endl;
}
};
complex operator - (const complex& z1, const complex& z2) {
return complex(z1.real - z2.real, z1.imag - z2.imag);
}
int main()
{
complex z1(3.14, 2.718), z2(6.18, 1.414), z3, z4;
z3 = z1 - z2;
z3.print();
z4 = operator-(z1, z2);
z4.print();
z4 = z1;
z4.print();
(z1 + z2).print();
z4.operator+(z2).print();
return 0;
}
![结果](https://img-blog.csdn.net/20171015130918425?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2luYXRfMjc0MjE0MDc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
运算符重载为友元函数
- 一般而言,重载为成员函数较好,因为普通函数不能访问私有成员
- 需要重载为普通函数时,将运算符重载为友元就可以访问私有成员了
friend complex operator - (const complex& z1, const complex& z2);
赋值运算符重载
- “=”只能重载为成员函数
- 赋值运算符两边类型不匹配时做些处理
- 赋初值,同类型的赋值,复制构造函数,都要考虑到,尤其成员变量是指针的时候
- 返回值最好是引用
- 浅拷贝无资源的释放分配,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间
- 深拷贝有资源的释放分配,是对指针指向的内容进行拷贝,故可避免内存泄漏
- 自己定义复制构造函数,里面释放原空间,申请新空间并赋值(深拷贝)
流插入和流提取运算符重载
iostream
中对“<<”和“>>”做了重载- 还想重载,只能重载为全局函数
程序实现
ostream& operator << (ostream& cout, const complex& z) {
cout << z.real << '+' << z.imag << 'i';
return cout;
}
int main()
{
cout << 5;
cout.operator<<(5);
cout << 6 << 7;
cout.operator<<(6).operator<<(7);
complex z = 3.9;
cout << z;
return 0;
}
类型转换运算符重载
- 在成员函数里定义重载函数,不写返回类型
(double)z
等价于z.operator double()
- 可以显式或者隐式的转换
自增自减运算符重载
- 前置运算符作为一元运算符来重载
- 后置运算符作为二元运算符来重载,多写一个没有用的参数即可
- 前置的重载时返回对象的引用,后置的返回修改前的对象
- 重载函数的参数需是引用
- 前置比后置运行更快,后置会生成临时对象
程序小测试
int a = 1;
++a = 6;
a++ = 8;