Страницы

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

четверг, 9 апреля 2020 г.

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

#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; }

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

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