C++对象销毁

标签 c++

我正在从 Java 转向 C++,我试图理解构造/破坏对象。 在 Java 中,当我这样做时

Myclass c=createANewObject();
c=createANewObject();

旧的 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");
}

而不是得到

Init -A-
Init -B-
destr.A
destr.B

因为我先创建A,然后创建B,然后A被销毁,范围结束所以B被销毁

我明白了

初始化-A-1456178128 初始化-B-1456178131 销毁B-1456178131 Destr.B-1456178131

所以我的 A 被创建了但没有被销毁,而 B... 被销毁了两次?

最佳答案

在 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 的末尾)销毁 main::c

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

注意。在 C++11 中,临时对象可以移入和移出(如果编译器决定不使用省略)而不是复制。但为了使列表简单,我将其排除在外。

关于C++对象销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35564587/

相关文章:

c++ - 跳过不兼容的 eclipse

c++ - 如何实现swap()?

C++ 定义变量设置值

c++ - 如何在C++中计算数字的第3个根

c++ - 可以执行 ffmpeg 而不使用他们的库吗?

c++ - 使用模板函数继承类

c++ - 在对象之间设置和获取变量而不引用它们

c++ - 运算符优先级与计算顺序

c++ - 从源代码 : configure: error: C compiler cannot create executables 构建 gcc 5.2.0

C++:类成员(变量)的前向声明