临时构造函数和复制构造函数

发布于 2024-10-08 08:02:18 字数 1664 浏览 0 评论 0原文

在下面的程序中,我尝试使用复制向量进行实验,有一点不清楚,当函数 f( ) 返回时,它应该使用复制向量为 < code>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);
} 

输出

HowMany2()
  h: objectCount = 1
Entering f()
HowMany2(const HowMany2&)
  h copy: objectCount = 2
x argument inside f()
  h copy: objectCount = 2
Returning from f()
HowMany2(const HowMany2&)
  h copy copy: objectCount = 3
~HowMany2()
  h copy: objectCount = 2  // Confused here !!!! why not h copy copy
~HowMany2()
  h copy copy: objectCount = 1
~HowMany2()
  h: objectCount = 0

With the below program, I tried to experiment with the copy ctor, there is one point which is not clear, when function f( ) returns it should use the copy-ctor to create a new object for h2, however I guess that is accomplished by the temporary object which uses the constructer of the object and then makes the copy however the destruction output shows that I am wrong on this reasoning... some clarification is appreciated on this problem ;)

#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);
} 

Output

HowMany2()
  h: objectCount = 1
Entering f()
HowMany2(const HowMany2&)
  h copy: objectCount = 2
x argument inside f()
  h copy: objectCount = 2
Returning from f()
HowMany2(const HowMany2&)
  h copy copy: objectCount = 3
~HowMany2()
  h copy: objectCount = 2  // Confused here !!!! why not h copy copy
~HowMany2()
  h copy copy: objectCount = 1
~HowMany2()
  h: objectCount = 0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌面超妹 2024-10-15 08:02:18

h copy copy 基本上是这一行中的 h2

HowMany2 h2 = f(h);

当您从 main 退出时,它会被破坏。

h copyf的参数,当f返回时它被破坏。由于fmain之前返回,因此h copyh 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();
} 

h copy copy is basically h2 from this line:

HowMany2 h2 = f(h);

It's destructed when you exit from main.

h copy is the argument of f, it's destructed when f is returning. Since f returns before main, h copy is destructed before h copy copy.

Note that RVO (return value optimization) was done by the compiler. There are no temporaries created in this code. Actually this code may output different results depending on the compiler. The compiler is free to do 1 or 2 invocations of the copy constructor in this code. (Maybe zero is also possible in this case, I don't know how to justify it though.)

Edit: Your code is implemented by the compiler like this (pseudo-code):

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();
} 
分開簡單 2024-10-15 08:02:18

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

At that "confusion" point, the temporary local object of function f is destroyed ("h copy"), after it has been returned to create the copy outside the function ("h copy copy"). Then, the objects outside the function are destroyed in reversed order of their creation: the copied object ("h copy copy") and, finally, the original object ("h").

聆听风音 2024-10-15 08:02:18

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 上的优化转为 full -O3 或在 VisStudio 中以发布模式构建。查看输出有何不同。

The return value from f() is doing a copy construction back to main.
The result puts the value into the variable h2.

Thus the parameter x in the function is destroyed first (as it leaves the function).
Then h2 then h as the main function exits and its local variables are destroyed.

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

If you want to get really freaked out. Turn the optimizations to full -O3 on gcc or build in release mode in VisStudio. See how the output differs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文