new 然后放入 C++构造函数?

发布于 2024-12-23 07:02:43 字数 281 浏览 5 评论 0原文

如果我这样做,

Bat::Bat() : m_member_str(new std::string("Am I freed?"))
{
  throw std::runtime_error("oops");
}

分配的std::string是否被释放?我想这可能是因为析构函数没有被调用。

我没有使用 std::string,而是我自己的类,只是将其显示为一个简单的示例。

If I do

Bat::Bat() : m_member_str(new std::string("Am I freed?"))
{
  throw std::runtime_error("oops");
}

Is the newly allocated std::string freed? I was thinking it might be because the destructor is not called.

I am not using a std::string, but my own class, just showing it as an easy example.

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

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

发布评论

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

评论(4

◇流星雨 2024-12-30 07:02:43

这个例子是智能指针的经典用例。 Bat 未完全构造,因此不会调用析构函数,但会调用 m_member_str 和所有其他完全构造的成员的析构函数。如果你不想像 try { foo(); 这样丑陋的块} catch (...) { 删除 m_member_str; },您必须熟悉 RAII。

std::auto_ptrboost::scoped_ptr 将在 C++03 或 C++11 中的等效项中为您提供帮助。将它们用于拥有的成员指针几乎没有什么缺点。

This example is the classic use case for smart pointers. Bat is not fully constructed, so the destructor won't be called, but the destructor for m_member_str and all other fully constructed members will be. If you don't want an ugly block like try { foo(); } catch (...) { delete m_member_str; }, you'll have to get comfortable with RAII.

std::auto_ptr or boost::scoped_ptr will help you in C++03, or their equivalents in C++11. There is very little disadvantage in using them for owned member pointers.

不忘初心 2024-12-30 07:02:43

完全构造的对象有其析构函数。
部分构造的对象则不然。

在您的情况下,您的 Bat 对象已部分构造,因为您从其构造函数中引发了异常。因此~Bat()不会被调用。

m_member_str 但是, 已完全构造,因此将调用其析构函数
但是,我们不可能看到该对象的类型。

如果它是 std::string* 那么什么也不会发生。它是一个指针,销毁指针并不会删除它指向的内存。

如果它是某种形式的智能指针,那么它的析构函数将被调用,并且它将安全地处理您分配的内存。

一般来说,只要你的成员是 RAII 对象并且有一个有意义的析构函数,无论如何它们都会被清理。

如果不是,就像在本例中一样,那么您必须自己处理后果,可能会捕获异常,释放内存,然后重新抛出。

Fully constructed objects have their destructor called.
Partially constructed objects do not.

In your case, your Bat object is partially constructed, because you threw an exception from its constructor. So ~Bat() will not be called.

m_member_str however, is fully constructed, and so its destructor will be called.
However, it is impossible for us to see the type of that object.

If it is a std::string* then nothing will happen. It is a pointer, and destroying a pointer does not delete the memory it points to.

If it is some form of smart pointer, then its destructor will be called, and it will safely handle the memory you allocated.

In general, as long as your members are RAII objects and have a meaningful destructor, they will get cleaned up no matter what.

If the are not, as in this case, then you have to deal with the consequences yourself, possibly bny catching the exception, freeing the memory and then rethrowing.

会傲 2024-12-30 07:02:43

不,除非您妥善处理,否则该对象将会泄漏。最好的方法是对成员变量使用智能指针。一般规则是,完全构造的对象在堆栈展开期间被销毁,这同样适用于 m_member_str 变量,但由于它是原始指针,析构函数将是微不足道的,不会触及指向的对象目的。

No, that object will be leaked unless you take care of it. The best way is to use a smart pointer for the member variable. The general rule is that fully-constructed objects are destroyed during stack unwinding and the same applies to m_member_str variable, but since it is a raw pointer the destructor will be trivial and won't touch the pointed-to object.

小…红帽 2024-12-30 07:02:43

你完全改变了你的问题 - 使我原来的答案无效! ;-P

新分配的字符串是否被释放?

我想这可能只是因为析构函数没有被调用

不相关。要进行释放,您基本上需要有一个构造对象,将为其调用析构函数,并在其中构造函数执行释放(或者您可以使用 try/catch 块并显式执行所有操作) 。

如果 m_member_str 是一个成员指针,我该如何释放它?

(首先,最好的通用方法是使成员变量 m_member_str 成为字符串而不是指向字符串的指针 - 然后字符串析构函数将进行清理。)

如果必须有一个指针,请使用智能指针捕获指针,以便智能指针的析构函数析构所指向的对象释放内存。当失败的构造函数在异常处理期间破坏已构造的成员变量时,将调用此函数。

You've completely changed your question - invalidating my original answer! ;-P

Is the string allocated with the new freed?

No

I was thinking it might be only because the destructor is not called

Not relevant. To get deallocation, you basically need to have a constructed object for which the destructor will be called, and in which the constructor performs deallocation (or you can use a try/catch block and do it all explicitly).

so how can I free m_member_str, if it was a member pointer?

(Firstly, the best general approach is to make the member variable m_member_str a string rather than a pointer-to-string - then the string destructor will clean up.)

If you must have a pointer, use a smart pointer to capture the pointer such that the smart pointer's destructor destructs the pointed-to object and deallocates the memory. This will be invokes as the failing constructor destroys already-constructed member variables during the exception handling.

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