从函数和复制构造函数返回的对象

时间:2011-09-27 13:41:33

标签: c++

有这样的代码:

#include <iostream>

class A {
public:
    int a;
    A() : a(0) {
        std::cout << "Default constructor" << " " << this << std::endl;
    }
    A(int a_) : a(a_) {
        std::cout << "Constructor with param " << a_ << " " << this << std::endl;
    }
    A(const A& b) {
        a = b.a;
        std::cout << "Copy constructor " << b.a << " to " << a << " " << &b << " -> " << this << std::endl;
    }
    A& operator=(const A& b) {
        a=b.a;
        std::cout << "Assignment operator " << b.a << " to " << a << " " << &b << " -> " << this <<  std::endl;
    }
    ~A() {
        std::cout << "Destructor for " << a << " " << this << std::endl;
    }
    void show(){
      std::cout << "This is: " << this << std::endl;
    }
};


A fun(){
  A temp(3);
  temp.show();
  return temp;
}


int main() {
    {
      A ob = fun();
      ob.show();
    }
    return 0;
}

结果:

Constructor with param 3 0xbfee79dc
This is: 0xbfee79dc
This is: 0xbfee79dc
Destructor for 3 0xbfee79dc

对象ob由函数fun()初始化。为什么没有在那里调用复制构造函数?我认为当函数按值返回时,将调用复制构造函数或赋值运算符。似乎函数fun()中构造的对象在执行函数后不会被销毁。在这种情况下,如何强制复制构造函数来调用?

这是由g ++编译的。

2 个答案:

答案 0 :(得分:4)

  

为什么不在那里调用复制构造函数?

RVO

  

在这种情况下,如何强制复制构造函数来调用?

将选项传递给编译器。对于gcc,禁用RVO是--no-elide-constructors选项

答案 1 :(得分:3)

这称为命名返回值优化复制省略,基本上意味着编译器已经发现可以通过小心地放置临时和对象在同一个内存位置。

默认情况下,该段代码中会有三个对象,temp内的fun,主要内部的返回值和ob,以及多达两个副本,但要小心将temp放在与fun内返回的对象相同的内存位置,并将ob放在同一内存地址中,可以优化掉两个副本。

我用两张图片写了关于这两个优化的文章来解释这里发生了什么:

相关问题