临时和复制构造函数

时间:2010-12-19 17:39:24

标签: c++ copy-constructor

使用下面的程序,我尝试使用copy ctor进行实验,有一点不清楚,当函数f( )返回时,应该使用copy-ctor为{{1创建一个新对象但是我想这是由临时对象完成的,它使用对象的构造函数,然后制作副本,但是破坏输出显示我在这个推理上错了...在这个问题上有一些澄清;)< / p>

h2

输出

#include <fstream>
#include <string>
using namespace std;
ofstream out("HowMany2.out");

class HowMany2 {
  string name; // Object identifier
  static int objectCount;
public:
  HowMany2(const string& id = "") : name(id) {
    ++objectCount;
    print("HowMany2()");
  }
  ~HowMany2() {
    --objectCount;
    print("~HowMany2()");
  }
  // The copy-constructor:
  HowMany2(const HowMany2& h) : name(h.name) {
    name += " copy";
    ++objectCount;
    print("HowMany2(const HowMany2&)");
  }
  void print(const string& msg = "") const {
    if(msg.size() != 0) 
      out << msg << endl;
    out << '\t' << name << ": "
        << "objectCount = "
        << objectCount << endl;
  }
};

int HowMany2::objectCount = 0;

// Pass and return BY VALUE:
HowMany2 f(HowMany2 x) {
  x.print("x argument inside f()");
  out << "Returning from f()" << endl;
  return x;
}

int main() {
  HowMany2 h("h");
  out << "Entering f()" << endl;
  HowMany2 h2 = f(h);
} 

3 个答案:

答案 0 :(得分:2)

h copy copy基本上是h2来自此行:

HowMany2 h2 = f(h);

退出main时会被破坏。

h copyf的参数,它在f返回时被破坏。由于fmain之前返回,h copy会在h copy copy之前被删除。

请注意,RVO(返回值优化)由编译器完成。此代码中没有创建临时值。实际上,根据编译器,此代码可能会输出不同的结果。编译器可以在此代码中自由地对复制构造函数进行1或2次调用。 (在这种情况下也许可能为零,但我不知道如何证明它。)

编辑:您的代码由编译器实现(伪代码):

void f(HowMany2 *result, HowMany2* xptr) {
  HowMany2 x(*xptr); // local copy

  x.print("x argument inside f()");
  out << "Returning from f()" << endl;

  new(result) HowMany2(x); // copy the return value

  x.~HowMany(); // destroy local copy
}

int main() {
  HowMany2 h("h");
  out << "Entering f()" << endl;
  HowMany2 h2; // not initialized
  f(&h2, &h);
  h2.~HowMany2();
} 

答案 1 :(得分:1)

在那个“混淆”点,函数f的临时本地对象被销毁(“h copy”),之后它被返回以在函数外创建副本(“h copy copy”)。然后,函数外部的对象按其创建的相反顺序销毁:复制的对象(“h copy copy”),最后是原始对象(“h”)。

答案 2 :(得分:0)

f()的返回值是将复制结构复制回main 结果将值放入变量h2

因此,函数中的参数x首先被销毁(因为它离开了函数) 然后h2然后h作为主函数退出并且其局部变量被销毁。

~HowMany2()
  h copy: objectCount = 2          // destruction of x
~HowMany2()
  h copy copy: objectCount = 1     // destruction of h2
~HowMany2()
  h: objectCount = 0               // festruction of h

如果你想真的吓坏了。在GCC上将优化转换为完全-O3或在VisStudio中以版本模式生成。看看输出有何不同。