我明白一点了,要是我在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分配的内存投掷出去,我又有点模糊了。
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分配的内存投掷出去,我又有点模糊了。
前一阵子仔细研究过只能指针,只能指针不适合作为参数(值传递),那也是同样的道理,例如这样的函数 HRESULT Do(IInterfacePtr p)是很不好的习惯,因为客户调用
IInterfacePtr p(...);
Do(p);
时,函数会把p复制成另一个参数,但是它不会调用职能指针的构造符,因此只能指针内部的实际指针没有调用AddRef,结果函数Do()退出之前p却调用析构函数注销自己,这时候,实际指针调用Release。运行结果出错。如果要让Do()同时适用实际指针和智能指针,代码方面还要下另一番功夫。
唉,最近找不到工作,只好天天研究这些东西。