3

我的智能指针实现如下所示,它不会在异常时释放内存..

template <class T>
class SMARTPOINTER
{
public:
   SMARTPOINTER(T* pointee) : SMART_POINTEE(pointee) {
    cout <<"\n Inside class SMARTPOINTER CONSTURCTOR \n";
   }

   ~SMARTPOINTER() {
     cout <<"\n Inside class SMARTPOINTER DESTRUCTOR \n";
      delete SMART_POINTEE;
   }

   T& operator*() const
   {
      cout <<"\n Inside class SMARTPOINTER operator* \n";
      return *SMART_POINTEE;
   }

   T* operator->() const
   {
      cout <<"\n Inside class SMARTPOINTER operator->()  \n";
      return SMART_POINTEE;
   }

private:
   T* SMART_POINTEE;

};

class Widget
{
public:

  Widget() {
      cout <<"\n Inside Widget CONSTRUCTOR \n";
  }

   void Fun() { 
     cout <<"\n Inside Widget::Fun() \n";
   }

  ~Widget() {
      cout <<"\n Inside Widget DESTRUCTOR \n";
  }

};

class THROWME{

};

int main() {

SMARTPOINTER<Widget> sp(new Widget);
sp->Fun();
throw new THROWME;
(*sp).Fun();

return 0 ;
}

我发现输出是

Inside Widget CONSTRUCTOR 

 Inside class SMARTPOINTER CONSTURCTOR 

 Inside class SMARTPOINTER operator->()  

 Inside Widget::Fun() 
uncaught exception of type THROWME*
Aborted.

据我所知,智能指针应该在这种情况下帮助我!!我没有发现通过智能指针调用 Widget 的破坏。

所以我必须在这里遗漏一些实现。

评论阅读后编辑

通过 try catch 我得到了我的结果。但我仍然不知道它的正确方法是否改变了代码

  int main() {
        try {
        SMARTPOINTER<Widget> sp(new Widget);
        sp->Fun();
        THROWME tm;
        throw tm;
        (*sp).Fun();
        }
        catch(...) {
          cout <<"\n **SOME EXCEPTION CAUGHT**  \n";
        }
        return 0 ;
        }

结果

 Inside Widget CONSTRUCTOR 

 Inside class SMARTPOINTER CONSTURCTOR 

 Inside class SMARTPOINTER operator->()  

 Inside Widget::Fun() 

 Inside class SMARTPOINTER DESTRUCTOR 

 Inside Widget DESTRUCTOR 

 **SOME EXCEPTION CAUGHT**
4

2 回答 2

4

析构函数的调用是堆栈展开的一部分,这是在异常“冒泡”调用堆栈时完成的……除非异常未处理。在这种情况下,堆栈是否展开是实现定义的

如果在程序中找不到匹配的处理程序,则调用函数terminate()( except.terminate)。在调用之前是否展开堆栈terminate()是实现定义的。

为了更优雅地处理这个问题,您可以使用函数 try 块:

int main()
try {
  // main body
} catch (...) {
  std::cerr << "Unhandled exception\n";
  std::terminate();
}

...尽管这会吞下异常并使其难以调试。

于 2013-06-01T08:46:09.613 回答
4

未调用析构函数,因为未处理的异常THROWME导致std::terminate调用。另请参阅此问题,特别是已接受答案中的第一个引号:

C++11 15.2 构造函数和析构函数 [except.ctor]

1 当控制从 throw 表达式传递到处理程序时,将为自进入 try 块以来构造的所有自动对象调用析构函数。自动对象按照其构建完成的相反顺序被销毁。

由于您没有 try 块来处理异常,因此不会调用析构函数。

于 2013-06-01T08:37:51.387 回答