Как использовать обработку исключений с помощью initializer-list с конструктором?

Я использовал, чтобы использовать 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
}
  • Проблема сейчас: они эксклюзивны? Я имею в виду Как смешать обработку исключений с Initialization-список через конструктор?

0

Решение

На первый взгляд, не ясно, намерены ли вы 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_;
};
2

Другие решения

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

По вопросам рекламы [email protected]