我明白一点了,要是我在main添加一行
int main(int argc, char* argv[]) 

  try 
  { 
    DoSome(); 
  } 
  catch(CMyException *pe) 
  { 
    pe->ReportError(); 
    pe->Delete(); //添加了这一行
  } 
  catch(...) 
  { 
    cout << "Unknown error happened." << endl; 
  }   return 0; 

那么程序运行结果如下(Release版本)
Exception construct
Exception destroy.
6552928 104 An error happened.  
Exception destroy.
但是Debug报错。因此我想throw &me的时候,它是把me的内存拷贝投掷出去的,但为什么Debug报错,涉及到调试器的内幕,我不懂。
不过要是把DoSome函数改成
void DoSome()
{
// CMyException me(_T("An error happened."));
// throw &me;
throw new CMyException(_T("An error happened."));
}
那运行结果就变了,不管是Debug还是Release版本,始终是
Exception construct
6552928 104 An error happened.  
Exception destroy.
因此我明白了  THROW(new CFileException(cause, lOsError, lpszFileName))这句调用,它重构了一个CFileException,即使你调用throw &e,对于catch块来说,获得的都是原异常对象的一份拷贝。
但是至于throw &e,与throw new e,为什么前者拷贝内存,后者仅仅是把new分配的内存投掷出去,我又有点模糊了。

解决方案 »

  1.   

    哦,我明白了,throw &e时,仅仅只是把e的内存拷贝一份投掷出去了,不会调用CFileException的构造函数,微软之所以采用 throw new CFileException(...)的方式,就是为了执行一遍构造函数。
    前一阵子仔细研究过只能指针,只能指针不适合作为参数(值传递),那也是同样的道理,例如这样的函数 HRESULT Do(IInterfacePtr p)是很不好的习惯,因为客户调用
        IInterfacePtr p(...);
        Do(p);
    时,函数会把p复制成另一个参数,但是它不会调用职能指针的构造符,因此只能指针内部的实际指针没有调用AddRef,结果函数Do()退出之前p却调用析构函数注销自己,这时候,实际指针调用Release。运行结果出错。如果要让Do()同时适用实际指针和智能指针,代码方面还要下另一番功夫。
    唉,最近找不到工作,只好天天研究这些东西。