C++对象销毁

Cic*_*cio 7 c++

我正在从java转向c ++,我试图理解构造/破坏对象.在java时,我这样做

Myclass c=createANewObject();
c=createANewObject();
Run Code Online (Sandbox Code Playgroud)

旧的c是垃圾收集的,另一个是用同一个名称创建的.

如果我尝试在c ++中做同样的事情我会得到奇怪的行为.

class my_class 
{
string content;
time_t t;
public: 
my_class(string c);
~my_class();
};

my_class::my_class (string c) 
{
content=c;
cout<<"Init -" << content << "-" << t <<endl;
}

my_class::~my_class()
{
cout<<"Destroyed -" << content << "-" << t <<endl;

}

my_class get_new_object(string s)
{
   my_class c(s);
   return   c;
}

int main()
{
    my_class c=get_new_object("A");
    c=get_new_object("B");
}
Run Code Online (Sandbox Code Playgroud)

而不是得到

Init -A-
Init -B-
destr.A
destr.B
Run Code Online (Sandbox Code Playgroud)

因为首先我创建A,然后创建B,然后A被销毁,并且范围结束,因此B被销毁

我明白了

Init -A-1456178128 Init -B-1456178131 Destr.B-1456178131 Destr.B-1456178131

所以我的A被创造而不被摧毁,而B ......被摧毁了两次?

M.M*_*M.M 8

在Java中,您的代码执行以下顺序:

  • 制作一个新对象
  • 设置引用c以引用该对象
  • 制作另一个新对象
  • c从旧对象释放引用并使其引用新对象
  • 旧对象现在没有引用,稍后将被垃圾收集

在C++中,您的代码是完全不同的.不要被类似的语法所迷惑.在C++中,您可以执行与Java代码几乎相同的步骤; 通过使用不同的语法.但您实际使用的语法执行以下操作:

  • 做一个对象 get_new_object::c("A")
  • 返回该对象的副本
  • 摧毁 get_new_object::c
  • main::c通过复制返回的副本来初始化对象
  • 销毁返回的副本
  • 做一个对象 get_new_object::c("B")
  • 返回该对象的副本
  • 摧毁 get_new_object::c
  • main::c通过从返回的对象复制细节进行更新
  • 销毁返回的对象
  • (在主要结束时)毁灭 main::c

可以通过称为复制省略的过程来优化上述一些副本.如果你使用编译器开关来禁用复制省略,你应该看到所有上述步骤,即5个析构函数,2个普通构造函数,以及(如果你还为其他特殊函数添加输出),3个复制构造函数和1个赋值运算符.

NB.在C++ 11中,临时对象可以移入和移出(如果编译器决定不使用elision)而不是复制.但是我把它留下来以保持清单简单.

  • 我在这里使用`::`作为伪代码(你实际上不能那样引用局部变量) (2认同)

mks*_*eve 1

这在某种程度上是特定于编译器和版本 ( C++11) 的。

get_new_object创建一个条目,并按值返回它。这可能会创建 3 个对象、2 个对象或 1 个对象。

3 个对象

编译器创建一个堆栈对象。这会将复制构造函数放入临时构造函数中。该临时文件使用另一个复制构造函数移至 C 中

2 个对象

更智能的编译器会丢失中间的临时值。

1 个对象

一个非常聪明的编译器意识到只有一个结果很重要。c++11通过移动构造函数提供帮助。

将创建复制/移动构造函数,但不会在代码中报告。

析构函数准确地描述了创建的对象数量 (2)

a/b 难题

编译器认为它只需要 A。因此

 init A
Run Code Online (Sandbox Code Playgroud)

当b被创建时,就创建了一个新对象。这是构造成的副本c

Init b
Run Code Online (Sandbox Code Playgroud)

然后 b temp 被破坏。

Destr b
Run Code Online (Sandbox Code Playgroud)

然后就c被毁了

destr b
Run Code Online (Sandbox Code Playgroud)