C++运算符重载

C++运算符重载

好吧 虽然很晚了 已经1:30分了 看我能熬到什么时候把   该死的心里作业.......

运算符重载呢 实质上就是函数重载 这里 我们不讲那么又臭又长的各种定义 直接上代码 PS:可能我讲的很无头绪  见谅.......

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class point
 5 {
 6 public:
 7     point(int xx =0 , int yy = 0  ):x(xx),y(yy){};
 8     point operator+(  const point& ptr)const
 9     {
10         return point( x+ptr.x , y+ptr.y );
11     }
12     void show()
13     {
14         printf( "x----%d
y---%d
",x,y );
15     }
16 private:
17     int x;
18     int y;
19 };
20 
21 int main()
22 {
23     point p(3,4);
24     point t(5,6);
25     point q;
26     q = p+3; 
27     q.show();
28 
29     q = p+t;
30     q.show();
31     getchar();
32 }
View Code

我们先看第26行: q = p+3; 因为这里的运算符重载方式 我们选择的是 类的非静态成员函数  所以 如果你一不小心 写成了 q = 3+p;那么 恭喜 编译肯定是不会过的

这里 你可能会好奇 这里的point类的 加号 运算符 不应该是2个point类的对象之间的运算吗? 为什么3可以进行计算呢?

嗯 因为呢 很巧合的是 这里point类的构造函数的形参恰好是int型的 更巧的是 我们还给形参默认了初始值 那么C++的编译器就会在进行计算时候 为我们进行隐式转换

所以你可以看成这样一个式子 q = p+(3,0)

当然 可能这不是你想要的    你可能不想要这种隐式转换的情况发生  能解决吗? 当然可以!  C++ 为我们提供了 explicit 关键字  它的作用呢 也很好理解  在构造函数前加上即可

这样以后 它会阻止隐式转换的进行 一定要显示进行   下面这段代码会有助于你的更好理解

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class a
 5 {
 6 public:
 7     a(int xx):x(xx)
 8     {
 9         cout<<"a"<<endl;
10     }
11 private:
12     int x;
13 };
14 
15 class b
16 {
17 public:
18     explicit b(int yy):y(yy)
19     {
20         cout<<"b"<<endl;
21     }
22 private:
23     int y;
24 };
25 
26 int main()
27 {
28     a A(4);
29     a AA = 5;
30     b B(6);
31     //b BB = 7;   你可以将注释去掉 再运行一下 就能发现了
32     getchar();
33     return 0;
34 }
View Code

ok 当然 有时候 还有另一种 情况  我想q = p+3;实现的是 q的横纵坐标 都+3  而不是仅仅x+3  这样应该如何实现呢?

其实 这实现起来也很简单 相当于 为函数形参为int的写一段'+'运算符的函数就可以解决了     只是我们的书上并没有提到

1 point operator+(int m)
2 {
3       return point(x+m,y+m);
4 }
View Code

好 接下来 来解决 第8行中的2个const的作用 

我们先来看修饰函数返回值的const,顾名思义,它的作用是使调用该运算符的对象的数据不被修改   所以其实一般我们仅仅重置‘+’ ‘-’ 其实是可有可无的 我们一般不会破坏

调用的函数对象的数据   为了安全 你当然可以写上  但是不要画蛇添足了  当你调用‘++’ ‘--’时 你的目的就是修改调用对象的数据 就不能加上const了

这里要注意区分 前置++ 与后置++的不同 前置是一定不能有const的 后置是可以带的

我们再来看下修饰函数形参中的const

你可以发现 当我去掉了这个const 编译是无法通过的 这是出现了什么问题呢?

这是编译的歧义所造成的:因为我们的重载加号运算符没有对int指定操作,那么当我们加上一个int的时候,无法确定一个常量数怎样映射到一个类,就会出现a right-hand operand of type 'const int'的歧义。

const修饰用在函数参数中,主要作用是防止函数修改该参数(因为地址传送中,通常传入的都是可修改变量);

我们还可以这样理解 这里的 3是一个常量 则由3发生的隐式转换得到的point类的对象 也应该被看做常值 即是等号的右值

然后 很重要的一点 : 在C++中 右值是不能传引用的  除非使用const修饰    下面这段代码会帮助你更好的理解

 1 #include <iostream>
 2 using namespace std;
 3 
 4 void a( int x)
 5 {
 6     cout<<"a"<<endl;
 7 }
 8 
 9 void b( int& x)
10 {
11     cout<<"b"<<endl;
12 }
13 
14 void c(const int& x)
15 {
16     cout<<"c"<<endl;
17 }
18 
19 int main()
20 {
21     a(5);
22     //b(2);
23     c(0);
24     getchar();
25     return 0;
26 }
View Code

至于解决方法 自然很简单 有2种  一个就是你加上const 另外就是自己再重载一个形参为int的加号运算符

上面所提的 都是自己所遇到的问题  可能有的地方 还是有错误不当之处 麻烦留言 让我更改~

至于类的非成员函数   你只要在是否声明为友元函数时 注意下是否需要调用类的私有和保护成员来决定

而 什么时候应该使用类的非成员函数  什么使用类的成员函数     =我有了更深的感悟再说吧

也差不多 该睡了  明天还要上课 ..~

相关推荐