Thread: Overloading Functions within a Matrix Class

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    1

    Overloading Functions within a Matrix Class

    I am having a problem with overloading an operator within a class structure. Below is
    the program that illustrates my problem. It defines a class Matrix, creates two matrices
    and multiplies them.

    I created two multiplication methods. The first is a straight function, the second uses
    the overloaded * operator. The two methods produce different results.


    Code:
    #include <fstream.h>
    
    class Matrix
     {
      private:
        int ROWS, COLUMNS;
        double *M;
      public:
        Matrix() { };                                                         //default constructor
        Matrix(int R, int C){ROWS=R; COLUMNS=C; M=new double[ROWS*COLUMNS];}; //constructor
        ~Matrix() {delete[] M;};        // destructor
        int rows() {return ROWS;}
        int cols() {return COLUMNS;}
        void set(int R, int C) {ROWS=R; COLUMNS=C; M=new double[ROWS*COLUMNS];};
        void m (int R, int C, double V) {M[R*COLUMNS+C]=V;};
        double m (int R, int C) {return M[R*COLUMNS+C];};
        void dump() {for (int r=0; r<ROWS; r++) {for (int c=0; c<COLUMNS; c++)
                        cout << M[r*COLUMNS+c]<< " "; cout << endl;};};
        void dump(fstream &fout) {for (int i=0; i<(ROWS*COLUMNS); i++)
                        {fout << M[i]; if (i!=(ROWS*COLUMNS-1)) fout << ", ";};};
        Matrix operator * (Matrix &);
      };
    
    Matrix Matrix::operator* (Matrix &B)
     {
      Matrix C;
      double ans;
      C.set(rows(), B.cols());
      for (int r=0; r<rows(); r++)
        for (int c=0; c<B.cols(); c++)
          {
           ans=0;
           for (int i=0; i<cols(); i++)
             ans=m(r,i)*B.m(i,c)+ans;
           C.m(r,c,ans);
          };
      return(C);
     };
    
    void multiply(const Matrix &A, const Matrix &B, Matrix &C)  //This Works!! Or at least seems to
    {
     double ans;
     C.set(A.rows(), B.cols());
     for (int r=0; r<A.rows(); r++)
       for (int c=0; c<B.cols(); c++)
         {
          ans=0;
          for (int i=0; i<A.cols(); i++)
            ans=A.m(r,i)*B.m(i,c)+ans;
          C.m(r,c,ans);
         };
    };
    
    
    void main()
      {
        Matrix A(4,3);
        Matrix B(3,6);
        Matrix C;
    
        A.m(0,0,11); A.m(0,1,12); A.m(0,2,13);
        A.m(1,0,21); A.m(1,1,22); A.m(1,2,23);
        A.m(2,0,31); A.m(2,1,32); A.m(2,2,33);
        A.m(3,0,41); A.m(3,1,42); A.m(3,2,43);
    
        B.m(0,0,11); B.m(0,1,21); B.m(0,2,31); B.m(0,3,41);B.m(0,4,51);B.m(0,5,61);
        B.m(1,0,12); B.m(1,1,22); B.m(1,2,32); B.m(1,3,42);B.m(1,4,52);B.m(1,5,62);
        B.m(2,0,13); B.m(2,1,23); B.m(2,2,33); B.m(2,3,43);B.m(2,4,53);B.m(2,5,63);
    
        C=A*B;
        A.dump(); cout << endl;
        B.dump(); cout << endl;
        C.dump(); cout << endl;
    
        multiply(A,B,C);
        A.dump(); cout << endl;
        B.dump(); cout << endl;
        C.dump(); cout << endl;
    
        cout << "Done.\n";
      }
    The "multiply" function produces the correct output, but the overloaded * method does not.
    That method produces:

    Code:
    4.13e-306 794 1154 1514 1874 2234
    794 1454 2114 2774 3434 4094
    1154 2114 3074 4034 4994 5954
    1514 2774 4034 5294 6554 7814
    This answer is mostly correct. Only the (0,0) cell is wrong, it should be 434.

    I have no idea what's going wrong here, other than I am getting the wrong answer.

    While I could just use the "multiply" function, I suspect that my problem here may be
    more than just with the overloaded operator.

    Most documentation examples don't seem to cover classes of matrices -- so I may
    have errors on several levels here.

    Any advice, or suggestions, will be greatly appreciated.

    Thanks,

    Tom

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Firstly, this code is full of syntax errors, so it is hard to see how it compiles in the first place.

    Starting from there not being a header like <fstream.h> in C++ (though probably your somewhat out-of-date compiler has it) and main having to return int.

    Besides that you are using const references in the operator overload, and then calling non-const methods on those arguments.

    ------------

    If the code is the same, one should be implemented in terms of the other (Ok, perhaps you are planning to remove the multiply method if you figure this one out?)

    -------------

    As to the problem, you are violating the rule of three. If you are managing a resource (dynamically allocated array), you'll need to define the destructor, the copy constructor and the overloaded assignment operator. (Or better yet, use a std::vector<double> instead, in which case you won't need any of those.)

    As it is, when operator* returns by value, the copy gets a pointer to the array used in the function by C, but that object itself goes out of scope at the end of the function and releases the memory. Using deallocated objects is undefined behavior (e.g, when running the debug version, all the results I got were wrong).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Whats the best way to control a global class?
    By parad0x13 in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2009, 05:17 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Very handy matrix functions - part 1
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 05-20-2004, 10:38 AM

Tags for this Thread