簡體   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