簡體   English   中英

如何在構造函數的initializer-list中使用異常處理?

[英]How to use exception handling with initializer-list with constructor?

我曾經通過構造函數使用initialization list ,但一切進展順利。 但是現在我需要在類中進行一些exception handling

所以這是一些示例代碼:

1-無異常處理

class CVector{
    public:
        CVector(const int);
    protected:
        int* pInt;
        int size;
};

CVector::CVector(const int sz) :
    pInt{ new int[sz]}, size{ sz}{

}

上面的構造函數不會檢查是否傳遞了無效的大小,或者new失敗...

現在,我編輯了構造函數以處理異常:

2-帶有異常處理:

CVector::CVector(const int sz){
    size = sz;
    if(size <=0 )
        throw; // some exception object

    pInt = new int[sz];
    if(nullptr == pInt)
        throw; // some memory exception
}
  • 現在的問題:它們是排他性的嗎? -我的意思是如何通過構造函數將異常處理與初始化列表混合在一起?

乍看之下,不清楚您是否打算讓CVector負責擁有整數的動態性。 你可能會的。

幾乎可以肯定,您希望程序中的每個類最多管理一個動態資源(例如分配的內存)。 這是因為當資源不止一種時,工作變得很繁重。

在您的情況下,資源是int數組。 因此,讓我們賦予CVector責任,並使用unique_ptr來管理該責任:

#include <memory>
#include <cstddef>
#include <algorithm>

struct CVector
{
    CVector(std::size_t initial_size)
    : data_ { std::make_unique<int[]>(initial_size) }
    , size_ { initial_size }
    {
    }

    // we will probably want the vector to be copyable
    CVector(CVector const& other)
    : data_ { std::make_unique<int[]>(other.size_) }
    , size_ { other.size_ }
    {
        auto first = other.data_.get();
        auto last = first + other.size_;
        std::copy(first, last, data_.get());
    }

    // move consruction is defaultable because it is enabled for
    // unique_ptr

    CVector(CVector&&) = default;

    // assignment

    CVector& operator=(CVector const& other)
    {
        auto temp = other;
        swap(temp);
        return *this;
    }

    CVector& operator=(CVector&& other) = default;

    // no need for a destructor. unique_ptr takes care of it

    void swap(CVector& other) noexcept
    {
        using std::swap;
        swap(data_, other.data_);
        swap(size_, other.size_);
    }

private:
    // defer memory ownership to a class built for the job.
    std::unique_ptr<int[]> data_;
    std::size_t size_;
};

1)將大小驗證檢查提取到一個單獨的靜態方法中(很可能無論如何都會重復使用); 2)不再需要檢查new返回的值,如果失敗,則應引發std::bad_alloc異常。 因此您的代碼可以變成這樣:

class CVector{
public:
    CVector(const int);
    static int Validate_Size(int const size);
protected:
    int * m_pInt;
    int m_size;
};

int CVector::Validate_Size(int const size)
{
   if(size <= 0)
   {
      throw std::invalid_argument{};
   }
   return(size);
}

CVector::CVector(const int size)
:  m_pInt{new int[Validate_Size(size)]}
,  m_size{size}
{}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM