#cpp #классы #указатели #перегрузка_операторов #операторы
Закрыт. Этот вопрос не по теме. Ответы на него в данный момент не принимаются. Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском». Закрыт 4 года назад. Как перегрузить, например, оператор присваивания таким образом, чтобы он работал во время инициализации экземпляра класса? #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; }
Ответы
Ответ 1
Прежде всего хотел бы отметить, что данное предложение 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; }
Комментариев нет:
Отправить комментарий