C++运算符重载
好吧 虽然很晚了 已经1:30分了 看我能熬到什么时候把 该死的心里作业.......
运算符重载呢 实质上就是函数重载 这里 我们不讲那么又臭又长的各种定义 直接上代码 PS:可能我讲的很无头绪 见谅.......
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\ny---%d\n",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 }
我们先看第26行: q = p+3; 因为这里的运算符重载方式 我们选择的是 类的非静态成员函数 所以 如果你一不小心 写成了 q = 3+p;那么 恭喜 编译肯定是不会过的
这里 你可能会好奇 这里的point类的 加号 运算符 不应该是2个point类的对象之间的运算吗? 为什么3可以进行计算呢?
嗯 因为呢 很巧合的是 这里point类的构造函数的形参恰好是int型的 更巧的是 我们还给形参默认了初始值 那么C++的编译器就会在进行计算时候 为我们进行隐式转换
所以你可以看成这样一个式子 q = p+(3,0)
当然 可能这不是你想要的 你可能不想要这种隐式转换的情况发生 能解决吗? 当然可以! C++ 为我们提供了 explicit 关键字 它的作用呢 也很好理解 在构造函数前加上即可
这样以后 它会阻止隐式转换的进行 一定要显示进行 下面这段代码会有助于你的更好理解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
ok 当然 有时候 还有另一种 情况 我想q = p+3;实现的是 q的横纵坐标 都+3 而不是仅仅x+3 这样应该如何实现呢?
其实 这实现起来也很简单 相当于 为函数形参为int的写一段'+'运算符的函数就可以解决了 只是我们的书上并没有提到
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 point operator+(int m) 2 { 3 return point(x+m,y+m); 4 }
好 接下来 来解决 第8行中的2个const的作用
我们先来看修饰函数返回值的const,顾名思义,它的作用是使调用该运算符的对象的数据不被修改 所以其实一般我们仅仅重置‘+’ ‘-’ 其实是可有可无的 我们一般不会破坏
调用的函数对象的数据 为了安全 你当然可以写上 但是不要画蛇添足了 当你调用‘++’ ‘--’时 你的目的就是修改调用对象的数据 就不能加上const了
这里要注意区分 前置++ 与后置++的不同 前置是一定不能有const的 后置是可以带的
我们再来看下修饰函数形参中的const
你可以发现 当我去掉了这个const 编译是无法通过的 这是出现了什么问题呢?
这是编译的歧义所造成的:因为我们的重载加号运算符没有对int指定操作,那么当我们加上一个int的时候,无法确定一个常量数怎样映射到一个类,就会出现a right-hand operand of type 'const int'的歧义。
const修饰用在函数参数中,主要作用是防止函数修改该参数(因为地址传送中,通常传入的都是可修改变量);
我们还可以这样理解 这里的 3是一个常量 则由3发生的隐式转换得到的point类的对象 也应该被看做常值 即是等号的右值
然后 很重要的一点 : 在C++中 右值是不能传引用的 除非使用const修饰 下面这段代码会帮助你更好的理解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
至于解决方法 自然很简单 有2种 一个就是你加上const 另外就是自己再重载一个形参为int的加号运算符
上面所提的 都是自己所遇到的问题 可能有的地方 还是有错误不当之处 麻烦留言 让我更改~
至于类的非成员函数 你只要在是否声明为友元函数时 注意下是否需要调用类的私有和保护成员来决定
而 什么时候应该使用类的非成员函数 什么使用类的成员函数 =我有了更深的感悟再说吧
也差不多 该睡了 明天还要上课 ..~