2014-02-12 23 views
0

在最近的一次采访中的正确使用,有人问我来回答如果这个代码是安全的,如果是我会使用这样的:投放新的和明确的析构函数调用

template<class T> T *CTricky<T>::Safe_Or_Not (T *object) 
{ 

    object->T::~T(); 

    ::new (object) T; 

    return object; 

} 

我的回答是:这段代码是安全的,如果我需要通过调用它的析构函数来释放我的“对象”使用的资源,我会使用这种技术,但同时我不想释放我的“对象”并希望它保存它被放置在内存中(通过在此放置新内容来实现)。

我真的不想在面试中正确回答这个问题。我只是很好奇,看看我对布局新的和显式的析构函数调用的理解是否正确。

+1

[也许相关(http://stackoverflow.com/q/8829548/596781)。 –

+1

这就是为什么要为对象回收空间(和其他所有东西!),移动语义非常好。 –

回答

1

这是安全: 以下可能会产生内存泄漏:(https://ideone.com/70YqhM

Base* b = new Derived; 
b = Safe_Or_Not(b); 

派生的析构函数永远不会被调用。

与其他提名:

  • 没有空检查。
  • 异常安全性是不考虑
1

我认为一般的“显式析构函数调用+放置新的”逻辑是安全的。
但是,此代码并不安全,因为:
- 您不检查指针是否为空。 - 不考虑安全因素

+0

对于指针上未经检查的空值+1。 – DigitalEye

2

简短回答:虽然不一定会导致问题,但确实很安全。最大的问题是如果构造函数通过放置new抛出,你已经销毁了这个对象,但是堆栈放开会试图再次销毁它,导致未定义的行为。

虽然还有其他一些东西需要注意(例如,空指针),这可能是最不明显,最难以避免造成问题的东西(基本上,关于您唯一的选择是忍受未定义的行为和对最好的希望,或者在堆栈解除发生之前捕获异常并退出程序)。