new则抛出c++构造函数
new then throw in C++ constructor?
如果我做了
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_ptr
或boost::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
成为字符串,而不是指向字符串的指针——这样,字符串析构函数将会清理。)
如果必须有一个指针,使用智能指针捕获该指针,使智能指针的析构函数析构所指向的对象,并释放所分配的内存。当失败的构造函数在异常处理期间销毁已经构造的成员变量时,将调用该函数。
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- 奇怪的构造函数行为