Good day. Faced one task with operator overloading, in my case, the first was addition + for two matrices. I could not add two objects declared using the pointer and the operator new. An error was output; something like an expression should refer to an integer type ...

Matrix* matrixPA = new Matrix(3,3); Matrix* matrixPB = new Matrix(3,3); Matrix* matrixPC = new Matrix(3,3); matrixPC = matrixPA + matrixPB;// запись 1 // если я делал вот так matrixPC = matrixPA->operator+(matrixPB);-код //работал, но хотелось бы чтобы было как в записи 1 ... Matrix Matrix::operator+(Matrix* matrix) { return *sum(matrix); } Matrix Matrix::operator=(Matrix* matrix) { for (size_t i = 0; i < str; i++) { for (size_t j = 0; j < stolb; j++) { this->matrix[i][j] = matrix->matrix[i][j]; } } return *this; } 

sum: function sum:

 Matrix Matrix::sum(Matrix* matrix) { if (matrix.str == this->str && matrix.stolb == this->stolb) { Matrix *matrixC = new Matrix(str, stolb); for (size_t i(0); i < this->str; i++) for (size_t j(0); j < this->stolb; j++) matrixC->matrix[i][j] = this->matrix[i][j] + matrix->matrix[i][j]; return *matrixC; } else std::cout << "Матрицы должны быть одинаковых размерностей!" << std::endl; return *this; } 

But if this is the case,

 Matrix matrixPA(3, 3); Matrix matrixPB (3, 3); Matrix matrixPC(3, 3); matrixPC = matrixPA + matrixPB; ... Matrix Matrix::operator+(Matrix& matrix) { return sum(matrix); } Matrix Matrix::operator=(Matrix& matrix) { for (size_t i = 0; i < str; i++) { for (size_t j = 0; j < stolb; j++) { this->matrix[i][j] = matrix.matrix[i][j]; } } return *this; } 

sum: function sum:

  Matrix Matrix::sum(Matrix& matrix) { if (matrix.str == this->str && matrix.stolb == this->stolb) { Matrix matrixC(str, stolb); for (size_t i(0); i < this->str; i++) for (size_t j(0); j < this->stolb; j++) matrixC.matrix[i][j] = this->matrix[i][j] + matrix.matrix[i][j]; return matrixC; } else std::cout << "Матрицы должны быть одинаковых размерностей!" << std::endl; return *this; } 

then everything works. Why??

    2 answers 2

    You want to add two pointers, but the operator looks like

     Matrix Matrix::operator=(Matrix* matrix) 

    At least you need to use

     *matrixPA + matrixPB 

    or

     matrixPA->operator+(matrixPB) 

    Because otherwise, the compiler does not understand what you need: you only have the Matrix& + *Matrix operator, roughly speaking ... When the operators are overloaded, at least one argument must be an object of the class.

    But it’s good that you’re not getting anything: it’s a very unhealthy idea to override the addition of pointers. In addition, as you imagine further developments:

     matrixPC = matrixPA + matrixPB; 

    Pointer gets what ? Are you assigning a pointer to a new matrix? At the same time losing the old value? And, by the way, the matrix returned by your operator leads to a memory leak - you simply lose the pointer to the matrix created in the operator. So C ++, preventing you from doing what you want, has already protected you from a lot of trouble :)

    Well, why does the second code work? Because it is correctly written.

      Let's start with the fact that this assignment statement

       Matrix Matrix::operator=(Matrix* matrix) { for (size_t i = 0; i < str; i++) { for (size_t j = 0; j < stolb; j++) { this->matrix[i][j] = matrix->matrix[i][j]; } } return *this; } 

      incorrect, since in the general case two matrices can have different values ​​for the str and stolb . Therefore, loops inside an operator can lead to accessing memory that does not belong to dynamically allocated arrays.

      You should, first, override the copy assignment operator, since the given operator shown above is not one. In fact, this is a pointer assignment statement to a class object. The compiler implicitly defines for you a copying assignment operator, which will copy objects in a member way, which may not be what you expect as a result.

      Therefore, instead of this operator, which assigns a pointer, you need to define a copy assignment operator, whose declaration will look like this

       Matrix ? Matrix::operator =( const Matrix &matrix ); 

      Or completely prohibit assignment, defining the operator as deleted

       Matrix ? Matrix::operator =( const Matrix &matrix ) = delete; 

      As for the given code fragments, in this fragment

       Matrix* matrixPA = new Matrix(3,3); Matrix* matrixPB = new Matrix(3,3); Matrix* matrixPC = new Matrix(3,3); matrixPC = matrixPA + matrixPB;// запись 1 

      all three variables are pointers, and you try to add two pointers. However, such an operation for pointers in the language is not defined.

      Interface of this function

       Matrix Matrix::sum(Matrix* matrix) { if (matrix.str == this->str && matrix.stolb == this->stolb) { Matrix *matrixC = new Matrix(str, stolb); for (size_t i(0); i < this->str; i++) for (size_t j(0); j < this->stolb; j++) matrixC->matrix[i][j] = this->matrix[i][j] + matrix->matrix[i][j]; return *matrixC; } else std::cout << "Матрицы должны быть одинаковых размерностей!" << std::endl; return *this; } 

      also incorrect. The function should throw an exception, and not return a copy of the current object if the dimensions of the matrices do not match. In addition, there is a memory leak, because inside the function you dynamically create an object, and then return a copy of this object, and the memory for the initially created object is not deleted, and access to the pointer will be lost.

      You should overload the operators for objects, not pointers to them.

      Also keep in mind that if inside a class you dynamically allocate memory, you must explicitly define at least the copy constructor, the copy assignment operator, and the destructor.

      • followed your advice. - Semyon Shelukhin
      • @ SemyonShelukhin And they did the right thing. :) - Vlad from Moscow