如何使用带有构造函数的初始化列表进行异常处理?

How to use exception handling with initializer-list with constructor?

我曾经通过 Constructor 使用 initialization list,一切都很顺利。但是现在我的 class.

中需要一些 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
}

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}
{}

乍一看,不清楚您是否打算让 CVector 负责拥有整数的动态。你可能会。

几乎毫无疑问,您会希望程序中的每个 class 最多管理一个动态资源(例如分配的内存)。这是因为当有多个资源时,工作变得繁重。

在您的例子中,资源是 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_;
};