1. 首先创建一个基本的Integer类 实现一些普通的operator的重载。
a. 重载加法操作
b. 重载加等于操作
c. 重载等于操作
我想这三个重载操作可以放在第一部分,一起讨论。附上Integer类的代码,以及不同情况的测试代码及结果。
Integer类代码:
测试代码:
测试输出:
小结:
1) 可以看到,之前在类operator重载中使用到三个符号都被执行到了,而且可以看到先后顺序,一次是 += 、+ 、= ;值得注意的是后面 + 、= 出现的顺序可以看到操作符的执行先后顺序,从左至右。
2) 其次观察一下三个operator的实现部分代码,发现return的两个返回值都是不同的。
其实可以归纳出。如果是对某个类赋值操作的,因为是操作符直接对类的引用做修改,就返回*this ,这样就直接改了原来那个类了。
2.研究重载操作符的参数传递
既然是C++ 那++操作总要实现以下。一开始遇到了点问题 , 主要集中在对于重载操作符旁边括号里面塞什么东西。
参考《C++编程思想》 ,编译器在区分c++ 和 ++c 时,使用到了哑元常量值int,
如果在内部类里实现成员函数时,如果编译器看到 ++c这一形式那就使用operator++()的调用,如果看到c++ 就产生一个对operator++(int)函数体的调用。这样也就基本明白了哑元常量值的用处: 起标记作用,这个值却永不被使用。
下面是Integer类及两种++的实现代码:
测试代码:
测试输出:
小结:
1) 对于一元操作符的重载,不同的运行过程,肯定源于不同函数体的调用。2中认识到了 哑元常量值 的使用方法和目的。
2) 其余的一元操作符不再一一实现,总结下来就是要么直接改引用,要么生成个过渡类,为以后operator的赋值准备
3. 使用友元函数的方式实现几个两元操作符
Integer类、友元函数的实现、测试函数:
在友元类操作符重载中,发现里面对于操作符左边右边的定义更加直观了,但是在使用友元类重载等号的是时候发现,这个不可以,之后看了别人的报告, 得知 : 在C++中 ,
“ = “ 、” -> “ 、“ [ ] “ 、” () “ 、“ . ” 、是不能够被重载为友元函数的。
原因: C++为所有的类自动实现了以上提及的五个运算符的非静态成员函数的实现,如果全局内有实现了这四个操作符的友元函数,那就会产生矛盾,报错!
1) 编译器自动产生的operator= 函数证明,
Integer类以及测试代码:
测试结果:
2) 自定义成员函数operator= 证明,
如果在Interger类内部以其成员函数的形式实现了operator=,则不再调用编译器本身产生的operator= 函数体
类代码、测试代码、实现代码:
输出代码:
4 实现从用户定义类型向内置类型转换
说道运算符重载,有一个不得不说就是我们常用的 从用户定义类型想内置类型转换 ,这也是通过运算符重载达到的。
测试说明:本例中,我使用Person类和 Age类,Person类里面有姓名name、体重weight、年龄age这三个私有成员,而Age类里面只有一个age。此外写了一个调用年龄的函数getAgeOfSomething(Age); 通过在Person里写了一个类型转换函数operatorAge() 使得在getAgeOfSomething(Age)中可以直接传入Person参数,就类似与int 、float、double之间的参数转换。
测试类:
测试代码:
输出结果:
小结,运算符重载实现了,从用户定义类型想函数内置类型的转换!
5. 写个bool返回值的操作符重载
代码:
struct Point{
int x;
int y;
Point(){}
Point(int a,int b):x(a),y(b){}
bool operator==(const Point& pt){
if(x != pt.x || y != pt.y)
return false;
else
return true;
}
bool operator!=(const Point& pt){
if(x == pt.x && y == pt.y)
return false;
else
return true;
}
};
//测试
int main(){
Point p1(0,0);
Point p2(1,1);
Point p3(1,1);
if(p1 != p3)
cout << "p1 != p3 \n";
if(p2 == p3)
cout << "p2 == p3 \n";
return 0;
}
输出:
p1 != p3
p2 == p3