new则抛出c++构造函数

new then throw in C++ constructor?

本文关键字:c++ 构造函数 new      更新时间:2023-10-16

如果我做了

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

new ly分配的std::string空闲了吗?我想可能是因为没有调用析构函数。

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

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

std::auto_ptrboost::scoped_ptr将在c++ 03或c++ 11中帮助你。

完全构造的对象被调用析构函数。部分构造的对象不能。

在你的例子中,你的Bat对象是部分构造的,因为你从它的构造函数抛出了一个异常。所以~Bat()不被调用

然而,

m_member_str 完全构造的,因此它的析构函数将被调用。然而,我们不可能看到那个物体的类型。

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

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

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

如果不是,就像在这种情况下,那么您必须自己处理后果,可能通过捕获异常,释放内存然后重新抛出。

不,除非您对其进行处理,否则该对象将会泄露。最好的方法是对成员变量使用智能指针。一般规则是,完全构造的对象在堆栈展开期间被销毁,同样适用于m_member_str变量,但由于它是一个原始指针,析构函数将是琐碎的,并且不会触及指向的对象。

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

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

没有

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

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

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

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

如果必须有一个指针,使用智能指针捕获该指针,使智能指针的析构函数析构所指向的对象,并释放所分配的内存。当失败的构造函数在异常处理期间销毁已经构造的成员变量时,将调用该函数。