Home  >  Q&A  >  body text

c++析构函数可以使一个return-by-value的函数少执行一次拷贝构造函数,是什么原因?

PHPzPHPz2715 days ago648

reply all(2)I'll reply

  • 怪我咯

    怪我咯2017-04-17 13:19:04

    The reason is optimization.
    First analyze your program. a1 is an instance, a2 is one, getTest passes parameters by value, then there will be a Temp1, getTest has a return Temp2. ​​So there should be four in total. objects.

    However, the compiler will optimize, even if you disable optimization, there will be a little optimization. For example, the return value of getTest originally needs to call operator= according to the semantics. In fact, the compiler usually calls CTest1(const CTest1&) directly. 🎜>This constructor optimizes two constructions into one.

    In your code, if you comment out cout in the destructor, you will find that it is only constructed three times. Because if there is nothing in the destructor, the compiler will enable that optimization, which will have no functional effect on your code. Any impact. But if you enable cout, once it is optimized, the function of the code may not be correct.

    If you delete cout in the destructor, compile with gcc, and add parameters -O0 -fno-elide-constructors, there are actually still four objects.

    reply
    0
  • 高洛峰

    高洛峰2017-04-17 13:19:04

    CTest1 getTestObj(CTest1 obj)
    {
        return obj; /* copy */
    }
    
    int main()
    {
        CTest1 a1; // construct             
        CTest1 a2 = /* copy */ getTestObj(a1/* copy */);
        return 0;
    }

    Regarding return values, there is a way to save trouble for the compiler, called return value optimization (RVO - return value optimization). The compiler will omit one step of the object's COPY construction call. I don't know what compiler LZ uses. It is enabled by default on gcc (4.8.3), which means the result is like this:

    Constructor of CTest1:0
    Copy constructor of CTest1:1
    Copy constructor of CTest1:2
    //如果去掉注释 就会打印下面三句话
     destroy id:1 
     destroy id:2
     destroy id:0
    

    reply
    0
  • Cancelreply