• 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的加号运算符

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

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

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

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

    just follow your heart
  • 相关阅读:
    303. Range Sum Query
    【Leetcode】292. Nim Game
    【c++】函数默认参数
    [err]default argument given for parameter 3 of '***'
    [err]multiple definition of `***'
    【leetcode】290. Word Pattern
    【leetcode】283. Move Zeroes
    【leetcode】278. First Bad Version
    【leetcode】268. Missing Number
    【leetcode】263. Ugly Number
  • 原文地址:https://www.cnblogs.com/radical/p/3746852.html
Copyright © 2020-2023  润新知