【问题标题】:C++: What does the class destructor do?C++:类析构函数是做什么的?
【发布时间】:2015-02-04 06:30:55
【问题描述】:

C++:类析构函数有什么作用?

假设我们有一个对象“myObject”,并且有如下几个成员:

int a;
float b;
yourClass yourObject;
void hisMethod();

从我读到的,分配给“myObject”的内存是这样的顺序。

一旦调用析构函数,发生了什么?

在调用析构函数之后,在对象被销毁之前,从我阅读的内容来看,我仍然可以访问 (a) 对象“myObject”。 (b) 成员 yourObject (c) 成员 hisMethod()

我还能访问其成员吗?这是未定义的行为?

许多 C++ 书籍没有详细讨论它。 我在哪里可以找到有关它的更多详细信息?因为细节可以帮助我理解许多 C++ 规则,例如“除非在放置 new 之后,否则不要手动调用析构函数”。

[更新 1] 我提出我的问题是因为我看到了这个帖子: What does empty destructor do? 海报举例如下:

#include <iostream>
#include <set>


class a
{
public:
std::set <int> myset;
};

int main()
{
a object;
object.myset.insert(55);
object.~a();
object.myset.insert(20);
std::cout << object.myset.size();
}

海报获得: “* glibc detected * /.app: double free or corruption (fasttop):”,然后是“ABORT”。

这意味着:

object.myset.insert(20);

不会引发错误,这意味着手动调用析构函数后对象仍然存在。 它的类成员仍然可以被调用!

两次调用解构函数会报错。

[更新 1] 我在 QT Creator 中运行代码,当运行到 object.myset.insert(20);

它引发错误:

读取访问冲突:0x0,flags=0x0。

【问题讨论】:

  • 调用 dtor 会结束对象的生命周期。不要对它做任何事情。
  • “在调用析构函数之后,在对象被销毁之前”——你的意思是什么?根据定义,析构函数会销毁对象。
  • @Deduplicator。我知道规则。我只是想了解底层机制。
  • @5gon12eder,你确定对象被破坏了吗?根据我的阅读,情况并非如此。
  • 我们必须澄清销毁对象的含义。调用析构函数后,对象的生命周期已经结束,对它的任何操作都将调用未定义的行为。编译器不能(也不应该)捕获所有此类滥用(例如在您更新的帖子中的示例),因此它可能会愉快地编译代码,但在执行时可能会发生任意坏事。仅仅因为某些东西可以编译(甚至运行),这并不意味着它是有效的 C++。

标签: c++ class destructor


【解决方案1】:

如果是yourClass yourObject;,销毁后你不能访问你的对象,
因为编译器会在你开始执行之前抱怨。
在这种情况下(自动存储持续时间),范围是对象的生命周期,因此在销毁之后,您将处于名称 yourObject 不再为人所知的代码部分。

(析构函数和实际的内存释放是分开的,但两者都是连续发生的,不可能在它们之间放置一些自己的代码)。

如果你有一些指针,用newdelete分配一些东西:
是的,在delete 之后访问它是未定义的行为。

【讨论】:

    【解决方案2】:

    类的析构函数,即称为~class 的方法,会做任何你要求它做的事情。它不会释放内存。

    析构函数作为销毁对象过程的一部分被调用,这个过程通常也会在其析构函数运行后释放与对象关联的内存。根据创建对象的位置和方式,将发生不同的内存“释放”:

    • 在堆栈上,内存被堆栈帧指针更新隐式释放
    • 在堆上,它将通过将内存释放回堆来释放
    • 对于静态内存并没有真正释放

    【讨论】:

    • 这是否意味着在手动调用析构函数后,我们不能再引用该对象了,因为内存中没有这样的变量?或者也许我们仍然可以引用对象,只是发生了未定义的行为?
    • @user1914692 是的,如果您仍然有可用的“名称”,即。当前范围包括它,您可以访问它。但是“只是”未定义的行为“只是”一个有问题的错误,它可能会破坏你的程序,所以不要。
    猜你喜欢
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 2013-02-14
    • 2021-05-09
    • 1970-01-01
    • 2014-04-22
    • 2010-10-13
    • 1970-01-01
    相关资源
    最近更新 更多