在构造函数中抛出异常--是否安全,请大家讨论

myan 2001-11-27 06:36:45
这是不久之前我遇到的一个问题。例如我们封装Win32 mutex,
class MyError : public std::runtime_error {...};

class Mutex {
HANDLE hMutex_;
public:
Mutex(const char* name = 0, bool is_owner = false,
SECURITY_ATTRIBUTES* psa = 0)
:hMutex_(0)
{
hMutex_ = ::CreateMutex(psa, is_owner, name);
if (hMutex_ == 0)
throw MyError; // 注意这里
}
~Mutex() throw()
{
if (hMutex_)
::CloseHandle(hMutex);
}
// other stuff
};

最初我认为这样有可能导致内存泄漏,因为如果用户如下使用Mutex:
try
{
auto_ptr<Mutex> apMutex(new Mutex()); // 这里抛出异常
...
}
catch (...)
{
...
}
则可能导致分配给Mutex对象的那部分空间泄漏。结果证明我是错的。这与C++ new操作的方式有非常大的关系。所以我想把这个问题提出来,看看大家是怎么考虑的。
...全文
371 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
cber 2001-11-28
  • 打赏
  • 举报
回复
我记得在构造函数中抛出异常一般都是安全的,只是我们需要把已经分配好的资源释放掉就可以了
你的那个问题可以参考一下uninitialized_fill的做法,应该是在异常发生时会有一个rollback的动作。
ChrisSoft 2001-11-27
  • 打赏
  • 举报
回复
构造函数应该让他少做点工作。出了错很麻烦的。
ccddd123 2001-11-27
  • 打赏
  • 举报
回复
我记得mfc有的GDI类就是在构造是抛出异常的,不知道是不是记错了~
fengye 2001-11-27
  • 打赏
  • 举报
回复
MSDN里有Deep C++系列文章,也讨论过这些问题,如果手头有的话,不妨看看。
正如myan所说,构造函数抛出异常确实不会使new产生内存泄漏。
文中提到构造函数抛出异常的问题在于,当这个类用作基类、其他类的成员,以及模板参数时,会给对方带来麻烦。比如:
class B {
public:
B() throw(); // B()不想throw
A a; // A()会throw
};
这就麻烦了,要用罕见的,还未被大多数编译器支持的function try blocks
B::B()
try : a()
{ // function body of B()
}
catch(...)
{
}
在构造函数里抛出异常的用法,好处坏处都有。既然C++没有提供足够完美的解决方案,我还是倾向于不用,至少是有限制地用。
  • 打赏
  • 举报
回复
我认为会导致内存泄漏
NowCan 2001-11-27
  • 打赏
  • 举报
回复
在构造函数里抛出异常确实会导致内存泄漏。

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧