Как перегрузить, например, оператор присваивания таким образом, чтобы он работал во время инициализации экземпляра класса?
#include
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;
}
Комментариев нет:
Отправить комментарий