Coding practice: return by value or by reference in matrix multiplication?

I am writing this question with reference to this one that I wrote yesterday. After a little documentation, it seems clear to me that what I wanted to do (and what I consider possible) is almost impossible, if not impossible. There are several ways to implement it, and since I'm not an experienced programmer, I ask what choice you would take. I am explaining my problem again, but now I have some opportunities to study.

What I need

I have a Matrix class and I want to implement multiplication between matrices so that using the class is very intuitive:

Matrix a(5,2);
a(4,1) = 6 ;
a(3,1) = 9.4 ;           
...                   // And so on ...

Matrix b(2,9);
b(0,2) = 3;
...                   // And so on ...

// After a while
Matrix i = a * b;

What i got yesterday

operator* operator=, :

Matrix& operator*(Matrix& m);
Matrix& operator=(Matrix& m);

* Matrix (Matrix return = new Matrix(...)) , , :

return *result;

,

"-" , , , " " - * :

Matrix operator*(Matrix& m);
Matrix& operator=(Matrix& m);

* return , .

: . = & * . , : , , 1) 2) , , , .

, - , , , . , , . .

, - , , , . , , .

+3
5

, , , a * b , ++ , Matrix& operator=(Matrix& m). :

Matrix& operator=(Matrix const& m);

. :), const , m, .

operator*():

Matrix operator*(Matrix const& m) const;

[EDIT: const , promises *this, . , a * b * c - a * b const . , . ]

P.S. , ++ , , ( ) , .

+9

++ Scott Meyers, . , operator= operator*

Matrix& operator=(Matrix const& m);
Matrix operator*(Matrix const& m) const;

,

Matrix& operator*=(Matrix const& m);

operator*

Matrix operator*(Matrix const &m) const {
    return Matrix(*this) *= m;
}

, . , , , :)

+9

. Vadims. , , . 3x3 4x4. , :)

, . - , .

. (, a=b) ( ).

, , . -, void Matrix.TransFormMe() on b, , (a b) .

, "" , .

, API - . void TransformMe()' member transforming the contained matrix, Matrix contains only a Matrix GetTransformed() `, .

. MFC CString copy-on-write, .NET a String . (, StringBuilder), . Copy-On-Write , API , .

, , (.. ), - .

- copy-on-write boost, , .. Pseudocode :

class CowPtr<T>
{
     refcounting_ptr<T> m_actualData;
   public:
     void MakeUnique()
     {
        if (m_actualData.refcount() > 1)
           m_actualData = m_actualData.DeepCopy();
     }
     // ...remaining smart pointer interface...
}

class MatrixData // not visible to user
{
  std::vector<...> myActualMatrixData;
}

class Matrix
{
  CowPtr<MatrixData> m_ptr; // the simple reference that will be copied on assignment

  double operator()(int row, int col)  const
  {  // a non-modifying member. 
     return m_ptr->GetElement(row, col);
  }

  void Transform()
  {
    m_ptr.MakeUnique(); // we are going to modify the data, so make sure 
                        // we don't modify other references to the same MatrixData
    m_ptr->Transform();
  }
}
+3

... , , ( ):

void lupp();

L, U P. get_inverse(), lupp(), Matrix* Matrix::inverse. :

Matrix& operator=(Matrix const& m);
Matrix operator*(Matrix const& m);

.

, , . . , - , mutable. const .

+3

, , , . Matrix LU ( ):

const Matrix& get_inverse();
const Matrix& get_l();
const Matrix& get_u();
const Matrix& get_p();

All except constas they all call (if necessary):

void lupp();

This updates the cached L, U, and P. The same means get_inverse()that they call lupp () as well as sets Matrix* Matrix::inverse. This causes a problem with:

Matrix& operator=(Matrix const& m);
Matrix operator*(Matrix const& m);

equipment.

0
source

Source: https://habr.com/ru/post/1702206/


All Articles