C++ использование удаленной функции с unique_ptr, make_unique
Псевдокласс, выполняющий матричное дополнение, использующее std::unique_ptr в качестве члена данных для представления элементов. М-рядов, N столбцов. Класс настроен для типа M, N. Я пытаюсь выполнить сложение матрицы (C = A+B) и продолжаю получать эту ошибку из "error: use of Удаленная функция". Я пытаюсь сломать основы C++ с усложнением smart_ptrs, любые указатели относительно этой ошибки приветствуются.
Все участвующие функции (в ошибке) показаны ниже:
class Matrix{
private:
std::unique_ptr<T[]> array=std::make_unique<T[]>(M*N);
public:
Matrix();
Matrix( const Matrix& other );
inline Matrix operator+( const Matrix& other ) const;
const Matrix& operator=( const Matrix< M, N, T >& other );
}
Matrix::Matrix(const Matrix& other)
{
*this = other;
}
inline Matrix
Matrix::operator+( const Matrix& other ) const
{
Matrix result(*this);
result += other;
return result;
}
const Matrix&
Matrix::operator=( const Matrix& other )
{
if(this != &other)
this->array = std::move(other.array);
return *this;
}
Места сообщения об ошибках:
error: use of deleted function ‘matlib::Matrix<2ul, 2ul, double>::Matrix(const matlib::Matrix<2ul, 2ul, double>&)’
Matrix< M, N, T > result(*this);
error: use of deleted function ‘std::unique_ptr<_Tp [], _Dp>& std::unique_ptr<_Tp [], _Dp>::operator=(const std::unique_ptr<_Tp [], _Dp>&) [with _Tp = double; _Dp = std::default_delete<double []>]’
this->array = std::move(other.array);
Заранее спасибо.
1 ответ
Как правило, большинство ваших ошибок происходят от std::unique_ptr
не имеет конструктора копирования. Это сделано для эффективного управления областью указателя внутри него. Одним из способов решения этой проблемы является создание нового std::unique_ptr
и скопируйте все отдельные значения.
Я написал пример класса для вас, возможно, это может помочь.
#include <memory>
template <class T>
class Matrix
{
private:
std::unique_ptr<T[]> data = nullptr;
size_t height, width;
public:
Matrix(size_t h, size_t w)
: height(h), width(w)
{
if(h*w == 0) return;
data = std::make_unique<T[]>(h*w);
}
Matrix(const Matrix& other)
{
height = other.height;
width = other.width;
data = std::make_unique<T[]>(height * width);
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
(*this)(j, i) = other(j,i);
}
}
}
Matrix operator=( const Matrix& other )
{
if(this == &other)
{
return *this;
}
height = other.height;
width = other.width;
data.reset(std::make_unique<T[]>(other.height * other.width));
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
(*this)(j, i) = other(j,i);
}
}
return *this;
}
T & operator()(size_t x, size_t y)
{
//If data is nullptr then this is undefined behaviour.
//Consider adding a throw or assert here
return data[y * height + x];
}
T operator()(size_t x, size_t y) const
{
//If data is nullptr then this is undefined behaviour.
//Consider adding a throw or assert here
return data[y * height + x];
}
size_t getHeight() const
{
return height;
}
size_t getWidth() const
{
return width;
}
};
В заключение, если вы хотите создать матрицы для математических целей, я предлагаю вам дать им статические размеры по соображениям производительности. Добавление математических операторов в такой класс требует дополнительной логики для случаев, когда измерения не совпадают. Матрицы статического размера решат эту проблему самостоятельно благодаря их типизации. Вы все еще можете сделать это так, но будьте осторожны с любыми крайними случаями.