• 1.7 C++基础知识_运算符重载_类外函数


    重载_+

    假设有下列代码,创建了三个变量a,b,c,其中c=a+b。

    1. int a = 1;
    2. int b = 2;
    3. int c = a + b;

    事实上,c = a + b中的“+”也是一个函数,不过这个函数是由编译器实现的。

    在之前的point.cpp代码中,如果使用+将两个坐标相加,看看会有什么结果。

    1. #include <stdio.h>
    2. #include <iostream>
    3. #include <string.h>
    4. #include <unistd.h>
    5. using namespace std;
    6. class Point {
    7. private:
    8. int x;
    9. int y;
    10. public:
    11. Point() {}
    12. Point (int x, int y) : x(x), y(y) {}
    13. int getX() { return x; }
    14. int getY() { return y; }
    15. void setX(int x) { this->x = x; }
    16. void setY(int y) { this->y = y; }
    17. void printInfo()
    18. {
    19. cout << "(" << x << ", " << y << ")" << endl;
    20. }
    21. friend Point add(Point &p1, Point &p2);
    22. };
    23. Point add(Point &p1, Point &p2)
    24. {
    25. Point n;
    26. n.x = p1.x + p2.x;
    27. n.y = p1.y + p2.y;
    28. return n;
    29. }
    30. int main(int argc, char **argv)
    31. {
    32. Point p1(1, 2);
    33. Point p2(2, 3);
    34. Point sum = add(p1, p2);
    35. sum.printInfo();
    36. return 0;
    37. }

    直接使用+将两个坐标相加。

    此时编译会报错,这是因为默认的+号是不支持两个坐标相加的。

    可以通过重载运算符将+号重载,让它支持坐标相加。

    首先,增加operator+函数。

    然后让它成为Point类的友员函数,这样就可以直接使用p1.x,p1.y,而不是通过getX这些函数获取坐标值。 

    最后,在main函数中直接使用+处理两个坐标即可。

    编译测试结果如下,可以看到结果符合预期。

     对于加减乘除,我们都可以使用这样的操作来重定向它们。

    重载_i++_++i

    同样的,对于前自加(++i)和后自加(i++),我们也可以使用operator来重定向他们。

    我们知道,对于名称相同的函数,我们通过不同的传参来区分他们。其中,前加加只带一个参数,后加加带两个参数。

    类似的,要在函数中直接操作类的成员,需要将函数设置为类的友员函数。

    在main函数中,先测试后自加,然后测试前自加。

     

    测试结果如下,其中第一个temp等于p1,第二个temp等于自加后的p2,符合预期。

    修改,增加构造函数和析构函数,再次编译看看。

    可以看到,调用++p的时候,系统会创建一个对象,然后在函数(前加加的函数)退出之后,我们没有使用这个对象,所以系统马上又销毁了这个对象。

    这个对象的创建和销毁会带来不必要的开销,我们尝试将这个开销优化掉。

     

    首先我们要了解为什么会创建这个对象。

    这个对象的创建是由于前加加的函数返回了一个Point对象

    实际上可以不用另外创建一个对象,我们直接返回传入的对象即可,只需要将返回值改为引用即可。

     修改后的前加加代码如下:

    测试的结果如下,可以看到修改后的代码,之前创建和销毁对象的log消失了。也就是说,多余的开销被清除了。

    需要注意一点,不要返回局部变量的引用,因为函数运行结束退出后,局部变量就会被销毁,此时它的引用其实就不存在了,这时候去操作它的引用,实际上操作的是一块无效的内存空间,这有可能引起程序的异常。

    重载_<<

    类似的,<<也可以重载,我们重载<<,直接输出坐标值。

    代码如下:

    编译执行,可以看到,直接使用cout<<p1,将坐标输出了。

    连续输出多个坐标也是没问题的。

     

     最后,我们重载的这些函数,其实也可以通过函数调用的方式直接调用他们,比如说:

    结果如下:

     可以看到,其实和++p这些的结果是一样的。

  • 相关阅读:
    SpringBoot整合SSM项目实战
    后端搜索条件
    Redis哨兵集群搭建
    WPF ObservableCollection 和 BindingList 有什么区别
    YOLOv5算法改进(7)— 添加单层注意力机制(包括代码+添加步骤+网络结构图)
    Flink开发语言大比拼:Java与Scala怎么选好?
    汽车红外夜视系统行业发展总体概况
    猿创征文|【C++游戏引擎Easy2D】我拿吃零食的时间,学会了在C++上添加可点击按钮
    Java设计模式之中介者模式
    关于电影的HTML网页设计-威海影视网站首页-电影主题HTM5网页设计作业成品
  • 原文地址:https://blog.csdn.net/qq_33141353/article/details/125307804