亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

構造函數拋出異常

構造函數拋出異常

C++
一只斗牛犬 2019-12-07 15:27:48
我正在與一位同事討論如何從構造函數中拋出異常,并認為我需要一些反饋。從設計的角度來看,可以從構造函數中拋出異常嗎?可以說我將POSIX互斥體包裝在一個類中,它看起來像這樣:class Mutex {public:  Mutex() {    if (pthread_mutex_init(&mutex_, 0) != 0) {      throw MutexInitException();    }  }  ~Mutex() {    pthread_mutex_destroy(&mutex_);  }  void lock() {    if (pthread_mutex_lock(&mutex_) != 0) {      throw MutexLockException();    }  }  void unlock() {    if (pthread_mutex_unlock(&mutex_) != 0) {      throw MutexUnlockException();    }  }private:  pthread_mutex_t mutex_;};我的問題是,這是標準的做法嗎?因為如果pthread mutex_init調用失敗,則互斥對象不可用,因此拋出異??纱_保不會創建互斥。我是否應該為Mutex類創建一個成員函數init并pthread mutex_init在其中進行調用以基于返回值返回布爾值pthread mutex_init?這樣,我不必為如此低級的對象使用異常。
查看完整描述

3 回答

?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

是的,從失敗的構造函數中引發異常是執行此操作的標準方法。閱讀有關處理失敗的構造函數的常見問題,以獲取更多信息。擁有init()方法也可以,但是創建互斥對象的每個人都必須記住必須調用init()。我覺得這違反了RAII原則。


查看完整回答
反對 回復 2019-12-07
?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

如果確實從構造函數引發異常,請記住,如果需要在構造函數初始化器列表中捕獲該異常,則需要使用try / catch語法。


例如


func::func() : foo()

{

    try {...}

    catch (...) // will NOT catch exceptions thrown from foo constructor

    { ... }

}


func::func()

    try : foo() {...}

    catch (...) // will catch exceptions thrown from foo constructor

    { ... }


查看完整回答
反對 回復 2019-12-07
?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

#include <iostream>


class bar

{

public:

  bar()

  {

    std::cout << "bar() called" << std::endl;

  }


  ~bar()

  {

    std::cout << "~bar() called" << std::endl;


  }

};

class foo

{

public:

  foo()

    : b(new bar())

  {

    std::cout << "foo() called" << std::endl;

    throw "throw something";

  }


  ~foo()

  {

    delete b;

    std::cout << "~foo() called" << std::endl;

  }


private:

  bar *b;

};



int main(void)

{

  try {

    std::cout << "heap: new foo" << std::endl;

    foo *f = new foo();

  } catch (const char *e) {

    std::cout << "heap exception: " << e << std::endl;

  }


  try {

    std::cout << "stack: foo" << std::endl;

    foo f;

  } catch (const char *e) {

    std::cout << "stack exception: " << e << std::endl;

  }


  return 0;

}

輸出:


heap: new foo

bar() called

foo() called

heap exception: throw something

stack: foo

bar() called

foo() called

stack exception: throw something

不會調用析構函數,因此,如果需要在構造函數中引發異常,則需要做很多事情(例如,清理嗎?)。


查看完整回答
反對 回復 2019-12-07
  • 3 回答
  • 0 關注
  • 530 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號