gpt4 book ai didi

c++ - 当对象超出范围时是否调用析构函数?

转载 作者:太空狗 更新时间:2023-10-29 23:10:51 26 4
gpt4 key购买 nike

例如:

int main() {
Foo *leedle = new Foo();

return 0;
}

class Foo {
private:
somePointer* bar;

public:
Foo();
~Foo();
};

Foo::~Foo() {
delete bar;
}

析构函数会被编译器隐式调用还是会发生内存泄漏?

我是动态内存的新手,所以如果这不是一个可用的测试用例,我很抱歉。

最佳答案

是的,自动变量将在封闭代码块的末尾被销毁。但请继续阅读。

您的问题标题询问当变量超出范围时是否会调用析构函数。大概你想问的是:

will Foo's destructor be called at the end of main()?

鉴于您提供的代码,该问题的答案是,因为 Foo 对象具有动态存储持续时间,我们很快就会看到。

这里注意什么是自动变量:

Foo* leedle = new Foo();

这里,leedle就是要销毁的自动变量。 leedle 只是一个指针。 leedle 指向的东西有自动保存期限,不会被销毁。所以,如果你这样做:

void DoIt()
{
Foo* leedle = new leedle;
}

您泄漏了 new leedle 分配的内存。


必须删除任何已分配给new的东西:

void DoIt()
{
Foo* leedle = new leedle;
delete leedle;
}

通过使用智能指针,这变得更加简单和强大。在 C++03 中:

void DoIt()
{
std::auto_ptr <Foo> leedle (new Foo);
}

或者在 C++11 中:

void DoIt()
{
std::unique_ptr <Foo> leedle = std::make_unique <Foo> ();
}

智能指针用作自动变量,如上所述,当它们超出范围并被销毁时,它们会自动(在析构函数中)删除 指向的对象。所以在上面的两种情况下,都没有内存泄漏。


让我们试着澄清一下这里的语言。在 C++ 中,变量具有存储持续时间。在C++03中,有3种存储时长:

1: automatic:具有自动存储持续时间的变量将在封闭代码块的末尾被销毁。

考虑:

void Foo()
{
bool b = true;
{
int n = 42;
} // LINE 1
double d = 3.14;
} // LINE 2

在这个例子中,所有变量都有自动存储期限。 bd 都将在第 2 行销毁。n 将在第 1 行销毁。

2:static:一个静态存储期的变量,会在程序开始前分配,程序结束时销毁。

3: dynamic:当你使用动态内存分配函数(例如,new)分配一个具有动态存储持续时间的变量时,它会被分配,当你使用时会被销毁使用动态内存分配函数(例如,delete)销毁它。

在我上面的原始示例中:

void DoIt()
{
Foo* leedle = new leedle;
}

leedle 是一个自动存储期限的变量,会在结束大括号时被销毁。 leedle 指向的东西具有动态存储持续时间,并且没有在上面的代码中销毁。您必须调用 delete 来释放它。

C++11 还添加了第四个存储持续时间:

4: 线程:线程开始时分配线程存储持续时间的变量,线程结束时释放。

关于c++ - 当对象超出范围时是否调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54535879/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com