Страницы

Поиск по вопросам

вторник, 25 июня 2019 г.

Работа перегруженного оператора во время инициализации экземпляра класса [закрыт]

Как перегрузить, например, оператор присваивания таким образом, чтобы он работал во время инициализации экземпляра класса?
#include ` using namespace std;`
class Matrix { private: int **Arr; int Size; public: Matrix(int SizeOfMatrix); Matrix operator = (Matrix &); };
int main() { Matrix A(4); Matrix B(4) = A; system("pause"); return 0; } Matrix::Matrix(int SizeOfMatrix) { Size = SizeOfMatrix; Arr = new int *[Size]; for (int i = 0; i < Size; i++) { Arr[i] = new int[Size]; for (int j = 0; j < Size; j++) Arr[i][j] = rand() % 50; } } Matrix Matrix :: operator =(Matrix &A) { for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) Arr[i][j] = A.Arr[i][j]; } return *this; }


Ответ

Прежде всего хотел бы отметить, что данное предложение
Matrix B(4) = A;
некорректное и не должно компилироваться. Фактически в данном предложении имеется два инициализатора: 4 и A
Но даже если вы правильно напишите
Matrix A(4); Matrix B = A;
то здесь вызывается не оператор присваивания, как вы думаете, а конструктор копирования, который определен компилятором неявно, и который просто почленно копирует члены данных объектов.
Когда вы динамически в классе распределяете память, то есть используете указатели, то вы должны определить явно по крайней мере конструктор копирования, копирующий оператор присваивания и деструктор. В противном случае поведение вашей программы может оказаться неопределенным. Например, в результате использования конструктора копирования, созданного компилятором неявно, может оказаться, что два объекта имеют указатели на одну и ту же область памяти, а потому при удалении этих объектов будет осуществлена попытка удалить одну и ту же память дважды.
Ваш класс может выглядеть следующим образом
class Matrix { private: int **Arr; size_t Size; public: explicit Matrix( size_t ); Matrix( const Matrix & ); ~Matrix(); Matrix & operator = ( const Matrix & ); };
Matrix::Matrix( size_t SizeOfMatrix ) : Arr( nullptr ), Size ( SizeOfMatrix ) { if ( Size ) { Arr = new int *[Size];
for ( size_t i = 0; i < Size; i++ ) { Arr[i] = new int[Size]; for ( size_t j = 0; j < Size; j++ ) Arr[i][j] = rand() % 50; } } }
Matrix::Matrix( const Matrix &rhs ) : Arr( nullptr ), Size ( rhs.Size ) { if ( Size ) { Arr = new int *[Size];
for ( size_t i = 0; i < Size; i++ ) { Arr[i] = new int[Size]; for ( size_t j = 0; j < Size; j++ ) Arr[i][j] = rhs.Arr[i][j]; } } }
Matrix::~Matrix() { for ( size_t i = 0; i < Size; i++ ) delete [] Arr[i]; delete [] Arr; }
Matrix & Matrix::operator =( const Matrix &rhs ) { if ( this != &rhs ) { int **tmp = nullptr;
if ( rhs.Size != 0 ) { if ( Size != rhs.Size ) { tmp = new int *[rhs.Size];
for ( size_t i = 0; i < rhs.Size; i++ ) { tmp[i] = new int[rhs.Size]; } } else { tmp = Arr; }
for ( size_t i = 0; i < rhs.Size; i++ ) { for ( size_t j = 0; j < rhs.Size; j++ ) tmp[i][j] = rhs.Arr[i][j]; } }
if ( Size != rhs.Size ) { for ( size_t i = 0; i < Size; i++ ) delete [] Arr[i]; delete [] Arr; }
Arr = tmp; Size = rhs.Size; }
return *this; }

Комментариев нет:

Отправить комментарий