繁体   English   中英

我应该在哪里捕获构造函数中引发的C ++异常?

[英]Where am I supposed to catch the C++ exception thrown in the constructor?

头文件:

#ifndef MUTEXCLASS
#define MUTEXCLASS

#include <pthread.h>

class MutexClass
{
private:
    pthread_mutex_t & _mutexVariable;
public:
    MutexClass (pthread_mutex_t &);
    ~MutexClass ();
};

#endif // MUTEXCLASS

源文件:

#include "mutexClass.h"
#include <stdexcept>

MutexClass::MutexClass (pthread_mutex_t & arg) : _mutexVariable (arg)
{
    _mutexVariable  = PTHREAD_MUTEX_INITIALIZER;
    int returnValue = pthread_mutex_lock (&_mutexVariable);
    if (returnValue > 0)
    {
        throw std::logic_error ("Mutex couldn't be locked!");
    }
}

MutexClass::~MutexClass()
{
    pthread_mutex_unlock (&_mutexVariable);
}

我应该在哪里捕获构造函数中引发的异常?

可以处理构造函数中引发的异常

  • 通过显式创建对象的代码( try { MutexClass m; ... } catch(const std::logic_error& e) { ... }
  • 通过代码创建一个包含MutexClass实例作为成员的对象(包括作为基本子对象...,即通过创建从MutexClass派生的对象的代码)
  • 通过代码调用创建异常的代码将展开堆栈,直到某些代码处理它们为止

请注意,对于较大对象的对象的构造函数中抛出的异常(对于has-ais-a关系),有一个棘手的部分。 如果成员的构造引发异常,则不会调用较大对象的析构函数...在传播异常之前,只有已构造的成员将被销毁。 例如一个类似的类:

struct Foo {
    MyData * data;
    MutexClass m;
    MyData() : data(new int[1000]) { }
    ~MyData() { delete[] data; } // NOT called if m constructor throws
};

如果MutexClass构造函数抛出异常,将泄漏内存。

同样在编写异常处理程序之前,请问自己是否捕获异常是正确的事情(即,如果您知道在发生这种情况时该怎么办)。 捕获异常并“隐藏”它是因为最糟糕的选择,因为在这种情况下您不知道该怎么办。

在特定情况下,如果您无法锁定新创建的互斥锁,您是否可以期望系统仍然处于良好状态,以使其保持运行状态是一个好主意?

与任何异常一样,您可以在堆栈中的任何地方处理异常。 这与处理函数中引发的异常没有什么不同。

在施工时

try {
  MutexClass m(arg);
}catch( std::logic_error const & e)
{
}

或者如果您有一个指针

try {
  MutexClass * m = new MutexClass(arg);
}catch( std::logic_error const & e)
{
}

如果您可以使用传递给函数的指针,请将该函数包围起来。

例如

无效funfun(MutexClass *);

try {
  funfun(new MutexClass(arg));
}catch( std::logic_error const & e)
{
}

如果要在初始化列表中构造对象:

class A
{
MutexClass mc;
A(pthread_mutex_t & m) try : mc(m)
{
} catch ( std::logic_error const & e )
{
// do something here to handle the failure 
// of mc(m) and the now the failure of A 
// must be handled in the construction point of A 
}
};

但是现在您还必须处理A构造函数的失败。

此外,您应该注意隐式转换和副本,而您的班级可悲地可复制。

void funfun(MutexClass m );   

pthread_mutex & m;
try
{
  void funfun(m);
} catch( std::logic_error const & e )
{
}

从构造函数抛出之前先阅读

也不要忘记,此类构造函数不适合用作静态成员。 所以这类课程可能会破坏您的程序

class maybreak 
{
private:

static MutexClass mc;

// ....

};

除非定义了包装函数方法,以在程序实际启动之后放置静态构造( COFU )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM