1

I have a self-defined Matrix class and want to overload operator * to do matrix multiplication:

template< int R, int C> 
class Matrix{
   int *_mat;
   int _size;
public:
   Matrix(){ _size = R*C; _mat = new int[_size]{0}; }
   ~Matrix(){ delete []_mat; }
   Matrix &operator=(const Matrix & m){/*...*/}
   //...
   template< int D2, int D1 > using matrix_t = int[D2][D1];
   template<int R2, int C2>
   Matrix<R,C2> operator*(const matrix_t<R2,C2> &mat)
   {
       Matrix<R,C2> result;
       for(int r = 0; r < R; r++)
       {
           for(int c = 0; c < C2; c++)
           {
               for( int i; i < C; i++ ){
                  /*do multiplication...
                    result._mat[r*C2+c] = ...
                  */
               }
           }
       }
       return result;
   }      
   //...
}; 

Then the problem comes with Matrix<R,C2> result. The result becomes a outside object of the class. So I cannot access its private member using like result._mat[r*C2+c].

What is the solution( without changing access permission) to define my function of matrix multiplication in this class?

Shindou
  • 506
  • 6
  • 15
  • you should be able to access the private member of another object from inside the same class. So result._mat[r*C2+c] should actually work? – Richard Jul 14 '15 at 11:52
  • @Richard `result._mat[r*C2+c]` dose not work in this case on VS2013. What do you mean by 'access the private member of another object' ? – Shindou Jul 14 '15 at 12:01
  • see http://stackoverflow.com/questions/14008200/a-private-variable-can-be-accessed-from-another-object-of-the-same-type – Richard Jul 14 '15 at 12:08
  • but if you have different templates (with different template args) then the compiler won't see it as the "same class" – Richard Jul 14 '15 at 12:11
  • @Shindou `Matrix< int R, int C>` and `Matrix< int R2, int C>` are not the same type. Just because the template is `Matrix` doesn't make the types the same. So you need to rethink your design. – PaulMcKenzie Jul 14 '15 at 12:20
  • I think your template can declare itself as a friend to get around the problem that being instantiated with different template parameters makes it a different class. I haven't done such things myself, so I'd need to experiment with the syntax in order to make this a real answer. – JSF Jul 14 '15 at 12:20
  • @JSF I have just tried this effort but can not work it out. Have you worked it out? – Shindou Jul 14 '15 at 13:34

2 Answers2

1

You cannot, you can just write function like set

void set(int index, int value)
{
   // check index
   _mat[index] = value;
}

And then in multiplication function just call result.set(...). Instead of

result._mat[r*C2+c] = ...

just

result.set(r*C2+c, ...);

This situation is since Result is object of type Matrix<R, C2>, that is not the same type as Matrix<R, C>, so you cannot access private members of type Matrix<R, C2> in member function of type Matrix<R, C>.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • 1
    The type of `*this` in your example is `Matrix` and thus could not assign to `result`... – Shindou Jul 14 '15 at 11:57
  • `result._mat[...] = value;` in `void set(int, int, int)` then call `result.set(..)`? Somehow I can not understand this usage... – Shindou Jul 14 '15 at 12:15
  • I'm confused with the `result` in function `void set(int, int, int)` since it is neither declared inside the function nor passed by argument list...By the way I think @Richard just gave a nice method.. – Shindou Jul 14 '15 at 12:40
1

You could specify an operator so you can externally set the values of the matrix. Note you won't be able to use operator [] - since you can only use that with one argument (ref C++ [] array operator with multiple arguments?)

   int& operator() (int row, int col) { 
     // todo: check array bounds
     return _mat[C*row+col];
   }

Usage:

 result(r,c) = ...
Community
  • 1
  • 1
Richard
  • 2,994
  • 1
  • 19
  • 31