Свой оператор присваивания и перемещения для векторной матрицы
Задание состоит в том чтобы составить описание класса, обеспечивающего представление матрицы произвольного размера с возможностью вывода на экран подматрицы любого размера и всей матрицы. В классе должны быть следующие функции:
- конструктор по умолчанию;
- конструктор копирования (copy constructor);
- конструктор перемещения (move constructor);
- оператор присваивания (copy assignment);
- оператор перемещения (move assignment);
- функция вывода на экран всей матрицы;
- деструктор (destructor).
Вот реализация класса Matrix:
class Matrix{
private:
vector<int> arr;
vector<vector<int>> *mat = new vector<vector<int>>;
public:
Matrix(){}
Matrix(int x, int y){
for (int i = 0; i < x; i++){
for (int j = 0; j < y; j++)
arr.push_back(rand() % 89 + 10);
mat->push_back(arr);
arr.clear();
}
}
Matrix(const Matrix& matx){
cout << "copy" << endl;
mat = new vector<vector<int>>;
mat->assign(matx.mat->begin(), matx.mat->end());
}
Matrix(Matrix&& matx){
cout << "move" << endl;
mat->assign(matx.mat->begin(), matx.mat->end());
matx.mat->clear();
}
Matrix& operator=(const Matrix& matx){
delete mat;
cout << "copy0" << endl;
mat->assign(matx.mat->begin(), matx.mat->end());
return *this;
}
Matrix& operator=(Matrix&& matx){
cout << "move0" << endl;
delete mat;
mat->assign(matx.mat->begin(), matx.mat->end());
matx.mat->clear();
return *this;
}
void out(){
for (int i = 0; i < int(mat->size()); i++){
for (int j = 0; j < int((*mat)[i].size()); j++)
cout << (*mat)[i][j] << " ";
cout << endl;
}
cout << endl;
}
~Matrix(){
delete mat;
arr.clear();
}
};
Конструкторы копирования работают нормально. А вот операторы присваивания и перемещения выдают ошибку:
Первый этап обработки исключения по адресу 0x0FE6DF58 (msvcp120d.dll) в ConsoleApplication8.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFEEEFEF2.
Тело программы:
void main()
{
Matrix m1(2, 3), m2(m1), m3(move(m1)), m4;
m1.out();
m2.out();
m3.out();
m1 = *new Matrix(3, 2);
m4 = move(m3);
m1.out();
m3.out();
m4.out();
_getch();
}
Ответы (1 шт):
Для начала я бы перенес
vector<int> arr;
в единственный конструктор, где этот вектор используется, и не хранил бы его в классе. Зачем?...
Далее, перемещение - это и есть перемещение, а не копирование:
Matrix(Matrix&& matx)
{
cout << "move" << endl;
mat = matx.mat;
matx.mat = nullptr;
}
Оператор присваивания вообще уникален...
Matrix& operator=(const Matrix& matx){
delete mat;
cout << "copy0" << endl;
mat->assign(matx.mat->begin(), matx.mat->end());
return *this;
}
После удаления во второй строке mat - что вы пытаетесь делать с ним? Какое
mat->assign(matx.mat->begin(), matx.mat->end());
??? И с перемещающим оператором присваивания проблемы:
Matrix& operator=(Matrix&& matx)
{
delete mat;
mat = matx.mat;
matx.mat = nullptr;
return *this;
}
Словом, я бы делал так:
class Matrix
{
private:
vector<vector<int>> *mat = nullptr;
public:
Matrix(){}
Matrix(int x, int y)
{
mat = new vector<vector<int>>;
for (int i = 0; i < x; i++)
{
vector<int> arr;
for (int j = 0; j < y; j++)
arr.push_back(rand() % 89 + 10);
mat->push_back(arr);
}
}
Matrix(const Matrix& matx)
{
cout << "copy" << endl;
mat = new vector<vector<int>>;
*mat = *matx.mat;
}
Matrix(Matrix&& matx)
{
cout << "move" << endl;
mat = matx.mat;
matx.mat = nullptr;
}
Matrix& operator=(const Matrix& matx)
{
delete mat;
cout << "copy0" << endl;
mat = new vector<vector<int>>;
*mat = *matx.mat;
return *this;
}
Matrix& operator=(Matrix&& matx)
{
delete mat;
mat = matx.mat;
matx.mat = nullptr;
return *this;
}
void out()
{
if (!mat)
{
cout << "No matrix\n";
return;
}
for (int i = 0; i < mat->size(); i++)
{
for (int j = 0; j < (*mat)[i].size(); j++)
cout << (*mat)[i][j] << " ";
cout << endl;
}
cout << endl;
}
~Matrix()
{
delete mat;
}
};
int main()
{
Matrix m1(2, 3), m2(m1), m3(move(m1)), m4;
m1.out();
m2.out();
m3.out();
Matrix * tmp = new Matrix(3, 2);
m1 = *tmp;
delete tmp;
m4 = move(m3);
m1.out();
m3.out();
m4.out();
}