我有一个带有原始指针的情况,我无法更改为智能指针,因为它是界面的一部分(我不想破坏使用它的任何代码):
struct Foo
{
Foo();
~Foo();
int * m_pStuff; // public!
};
我不想在我的病人身上做太多事情。就像这样:
m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
m_pStuff[0] = 0;
然后在析构函数中删除它。
现在,我想知道使用try / catch是否值得围绕它:
Foo::Foo()
: m_pStuff(0)
{
try
{
m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
m_pStuff[0] = 0;
}
catch(...)
{
delete m_pStuff;
throw;
}
}
我可以看到的观点:
我可以看到的要点:
我还是犹豫不决:我是否应该尝试使用try / catch?为什么?我想就此发表意见。
此外,您是否看到在分配时由于内存不足而导致异常的可能性?在这种情况下,已经分配的内存将被自动回收,对吧?
谢谢!
答案 0 :(得分:5)
这完全没有意义。
int
构造可能不会抛出,因此这里唯一可能的例外是std::bad_alloc
。在这种情况下你在做什么?
delete
,这是一个无操作。分配失败,所以你不是“回收”任何东西。即。确切地说,没有try
/ catch
会发生什么。
只是让异常传播,并记录它是可能的。
但这个建议并不一定适用于其他类型。
另外,请不要忘记您的复制构造函数。
答案 1 :(得分:0)
在这种情况下,try catch中没有必要,因为如果你在新指针中得到std :: bad_alloc将是NULL并且它将导致删除NULL,它将什么都不做。
答案 2 :(得分:0)
只是附加信息
从构造函数中抛出异常是一个潜在的坏主意。看一下代码
class Foo
{
Foo(int* a, int* b): _a(a), _b(b)
{
}
public:
Foo() :
Foo(nullptr, nullptr)
// _a(nullptr), _b(nullptr)
{
_a = new int[10];
_b = new int[100500 * 100500]; // should throw an exception
}
~Foo()
{
delete[] _a;
delete[] _b;
std::cout << "~Foo()" << std::endl;
}
private:
int* _a;
int* _b;
};
int main()
{
try
{
Foo f;
}
catch(std::exception& e)
{
std::cout << "Catched: " << e.what() << std::endl;
}
}
此代码按预期工作:
〜富()
Catched:std :: bad_alloc
但如果我们评论Foo(nullptr, nullptr)
行并取消注释// _a(nullptr), _b(nullptr)
行,我们会看到此输出:
Catched:std :: bad_alloc
因此,新代码不会调用析构函数,因为对象未完全构造。我们有内存泄漏。