• 《Effective C++》条款21


    必须返回对象时,别妄想返回其reference

    如果你的运算符重载函数写成了返回reference的形式:

    1. class A
    2. {
    3. public:
    4. A(int a,int b):x(a),y(b){}
    5. friend const A& operator*(const A& a, const A& b);
    6. private:
    7. int x;
    8. int y;
    9. };
    10. const A& operator*(const A& a, const A& b)
    11. {
    12. A aa(a.x * b.x, a.y / b.y);
    13. return aa;
    14. }

    但是这样写是错误的,一旦使用引用返回前,一定要想清楚当前引用的对象在哪,是谁,而函数内的对象是在stack上创建的,一旦函数栈帧被销毁,那么该stack上的值也不复存在。那么引用它必然接收不到任何值。

    如果在heap上开辟对象:

    1. const A& operator*(const A& a, const A& b)
    2. {
    3. A* aa = new A(a.x * b.x, a.y / b.y);
    4. return *aa;
    5. }

    存在的问题是:

    1. A a, b, c, d;
    2. a = b * c * d;

    如果这样写,那么会调用两次operator* , 所以使用了两次new。同时就需要两次delete才能保证内存不泄露,但是却没有合理的办法让operator*使用者进行那些delete调用,因为没有合理的办法让他们取得operator*返回的引用指向一个被定义于函数内部的static A对象。

    如果定义对象为static类型:

    1. const A& operator*(const A& a, const A& b)
    2. {
    3. static A ret(0,0);
    4. ret= A(a.x * b.x, a.y / b.y);
    5. return ret;
    6. }

    存在的问题是:

    1.存在了线程安全问题。

    2.

    1. const bool operator==(const A& a, const A& b)
    2. {
    3. A a, b, c, d;
    4. if ((a * b) == (c * d))
    5. {
    6. }
    7. else
    8. {
    9. }
    10. }

    表达式(a * b) == (c * d)总是被核算为true,因为上述式子等价于:

    if(operator==operator*(a,b),operator*(c,d))

    两次operator确实改变了它们的值,但是由于它们返回的都是reference,因此调用者看到的都是static A对象的“现值”

  • 相关阅读:
    JS 的 apply 方法
    大数据Flink(七十二):SQL窗口的概述和Over Windows
    a-table 表格拖拽
    音频的“隐形保镖”——音频数字水印
    springboot项目实现helloworld
    UG\NX二次开发 关闭显示,隐藏创建过程,提高运行效率
    智能可观测性如何赋能智能汽车主机厂
    Paddle图神经网络训练-PGLBox代码阅读笔记
    突破5000篇!H3K27me3如何影响癌症发展。
    springboot集成mybatis
  • 原文地址:https://blog.csdn.net/qq_64863535/article/details/134469894