Writing a matrix class - how to access elements

Hi all,

I'm currently trying to write a class of matrices. The info at the following link has been very useful
http://www.cplusplus.com/forum/beginner/7609/

One thing I'm trying to do, but it won't work, is to simply print out an element so that I know it's working correctly. So using the codes given at the link above, I've tried

std::cout << first[1][2] << "\n";

but get the error

no match for 'operator[]' in 'first[1]'

Any ideas as to what I'm doing wrong?

Thanks,

Mike
first is a p2dArray object instead of the int** in the class declaration.

The compiler thinks that first[1] is calling an overloaded operator of the class (first.operator[]) but since there is no such operator in the class declaration it is flagged as an error.

So a solution would be overloading [], or designing some methods to access the contents.
Last edited on
use the () operator;

here is a small sample from a Matrix Class that I am writing
1
2
		T &operator()(int);
		T &operator()(int, int);

where T is a template typename.

the [] operator really only works with a linear coordinate system or arrays, but not as a class operator.

Edit 1( after Jun 24, 2009 at 3:19pm): you would then call say the first(0th) element by doing
myMatrix(0,0) or myMatrix(0) if you needed to view the matrix with linear coordinates for some reason.
Last edited on
Yes, exactly.

For the OP: Start reading at the C++FAQ-lite section 13.10 through 13.12
http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10

Good luck!
Thanks everyone, I've managed to sort it out.

I'm now overloading the * operator so that it will multiply a vector by a matrix (the following is in my matrixclass.hpp file):

friend matrixdouble_new operator *(const vectordouble& v, const matrixdouble_new& A);

but it won't compile. There's an issue with my vectorclass and matrixclass being defined in different files. I've tried including both header files in all the .cpp files but to no success.

What's the usual way of using different classes together?

Thanks,

Mike
That is the usual way. What compile errors are you getting?
In my matrixclass header file, when I try to include the vectorclass header file (i.e. vectordouble.hpp) it can't find it. I've checked and it's certainly in the same directory

vectordouble.hpp: No such file or directory.
In my matrixclass header file, when I try to include the vectorclass header file (i.e. vectordouble.hpp) it can't find it. I've checked and it's certainly in the same directory

vectordouble.hpp: No such file or directory.
did you

#include "vectordouble.hpp"

or

#include <vectordouble.hpp>

?

The first one is correct; the second one is wrong.

(the difference between the two is that angle brackets tell the compiler to search only the system include path and quotes tell the compiler to search the user include path first.)
as a side note: why don't you make your matrix and vector(not std::vector) template classes?
jsmith, I did

#include "vectordouble.hpp"

Here's some of my code which may enlighten things a bit. Firstly here's the matrixdouble_new.h file

[code]
// Matrix HEADER FILE
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include "vectordouble.hpp"

//using namespace std;

//typedef int p2dArrayData;

class matrixdouble_new
{
public:
// The default constructor
matrixdouble_new();
// General constructor for an m-by-n matrix
matrixdouble_new (int rows, int cols);
// The copy constructor
matrixdouble_new (const matrixdouble_new& A);

// Operators
// Overloading the = operator for our matrix class
matrixdouble_new& operator =(const matrixdouble_new &A);
// Overloading the binary + operator for our matrix class
friend matrixdouble_new operator +(const matrixdouble_new &A,
const matrixdouble_new &B);
// Overloading the binary - operator for our matrix class
friend matrixdouble_new operator -(const matrixdouble_new &A,
const matrixdouble_new &B);
// Overloading the unary + operator for our matrix class
friend matrixdouble_new operator +(const matrixdouble_new &A);
// Overloading the unary - operator for our matrix class
friend matrixdouble_new operator -(const matrixdouble_new &A);
// Overloading the () operator
double &operator()(int i, int j);
// Overloading the * operator:
// Multiplying a scalar by a matrix
friend matrixdouble_new operator *(const double& a, const matrixdouble_new& A);
// Multiplying a matrix by a scalar
friend matrixdouble_new operator *(const matrixdouble_new& A, const double& a);
// Multiplying a vector by a matrix
friend matrixdouble_new operator *(const vectordouble& v, const matrixdouble_new& A);

// Destructor
~matrixdouble_new();
// We define 'elem' as a pointer-to-a-pointer in order to dynamically allocate
// memory to our 2D array
double **elem;
int height;
int width;

private:
// int height;
// int width;
};[\code]

And the matrixdouble_new.cpp file

[code]
// We create a Matrix Class in this file
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include "matrixdouble_new.h" //This is our header file
#include "vectordouble.hpp"
.
.
.
// Multiplication of a vector by a matrix
matrixdouble_new operator *(const vectordouble& v, const matrixdouble_new& A)
{
double sum = 0.0; // This will store the scalar product of v with each column of A

// create a vector of size A.width
vectordouble u(A.width);

for(int i = 0; i < u.vector_size; i++)
{
sum = 0.0; //Re-initializing 'sum'

for(int j = 0; j < A.height; j++)
{
// for(int k = 0; k <A.height; k++)
// {
sum += v.x[j] * A.elem[j][i];
// }
}

u.x[i] = sum;
}
return u;
}
[\code]

and the main file

[code]
// MAIN FILE
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include "matrixdouble_new.h"
#include "vectordouble.hpp"

//using namespace std;

int main()
{
matrixdouble_new A(2, 3);
matrixdouble_new B(3, 2);

vectordouble v(2);
vectordouble u(3);
u = v*A;

return 0;
}
[\code]

Any insights would be greatly appreciated!

Is it possible that the compiler is getting confused? I'm using Dev-C++ and just compile my whole project (containing all the files above, along with vectordouble.hpp and vectordouble.cpp) in one go.

P.S. smilodon, that would be the nicer way to do it, but for the purposes of this assignment I have to do it this way.



Do you have #include guards around your header files?
jsmith, I didn't have guards around my matrixdouble header file, have just changed this but still getting compiling errors. Here are the error messages in all their glory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\byrnem6\My Documents\Oxford work\Courses\Cpp\Makefile.win"
Executing  make...
make.exe -f "C:\Documents and Settings\byrnem6\My Documents\Oxford work\Courses\Cpp\Makefile.win" all
g++.exe -c "Source files/matrixdouble_new.cpp" -o "Source files/matrixdouble_new.o" -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   

In file included from Source files/matrixdouble_new.cpp:5:
Source files/matrixdouble_new.h:9:28: vectordouble.hpp: No such file or directory
In file included from Source files/matrixdouble_new.cpp:5:
Source files/matrixdouble_new.h:48: error: expected `,' or `...' before '&' token
Source files/matrixdouble_new.h:48: error: ISO C++ forbids declaration of `vectordouble' with no type
Source files/matrixdouble_new.h:48: error: `matrixdouble_new operator*(int)' must have an argument of class or enumerated type

Source files/matrixdouble_new.cpp:207: error: expected `,' or `...' before '&' token
Source files/matrixdouble_new.cpp:208: error: ISO C++ forbids declaration of `vectordouble' with no type

Source files/matrixdouble_new.cpp:208: error: `matrixdouble_new operator*(int)' must have an argument of class or enumerated type
Source files/matrixdouble_new.cpp: In function `matrixdouble_new operator*(int)':
Source files/matrixdouble_new.cpp:212: error: expected `;' before "u"
Source files/matrixdouble_new.cpp:214: error: `u' undeclared (first use this function)
Source files/matrixdouble_new.cpp:214: error: (Each undeclared identifier is reported only once for each function it appears in.)
Source files/matrixdouble_new.cpp:218: error: `A' undeclared (first use this function)

Source files/matrixdouble_new.cpp:222: error: `v' undeclared (first use this function)

make.exe: *** ["Source files/matrixdouble_new.o"] Error 1

Execution terminated 


When it looks in matrixdouble_new.h for vectordouble.hpp, it can't find it. Is it even possible to include one header file in another? Then it gets down to line 48 where I'm trying to define my operator overload
1
2
// Multiplying a vector by a matrix
        friend matrixdouble_new operator *(const vectordouble& v, const matrixdouble_new& A);

and doesn't recognise it.
Source files/matrixdouble_new.h:9:28: vectordouble.hpp: No such file or directory

I think the problem is in here, it cannot find it.
(Can you edit the code you post so it is easier to track which line is which?)

By the way I spot another thing...
1
2
// Overloading the unary + operator for our matrix class
friend matrixdouble_new operator +(const matrixdouble_new &A);


It should have a this pointer but you declare it friend.

[EDITED] and another thing...
Why are height and width both public and private? Create accessor methods to get the private data.
Last edited on
hi wmheric

I've been playing around with the code since, but still have the same problems.

here's the problematic part of my matrixdouble_new.cpp file, formatted more helpfully

1
2
3
4
5
6
7
8
9
10
11
12
13
// We create a Matrix Class in this file
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include "matrixdouble_new.h" //This is our header file
#include "vectordouble.hpp"

// Overwriting the default constructor (cannot create a matrix without giving 
// the dimensions
matrixdouble_new::matrixdouble_new()
{
   std::cerr << "Attempt to generate a matrix without declaring the size\n\n";
}


and the matrixdouble_new.h header file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#ifndef MATRIXDEF
#define MATRIXDEF


// HEADER FILE
#include <iostream>
#include <iomanip>
#include <stdlib.h>
//#include "vectordouble.hpp"

//using namespace std;

//typedef int p2dArrayData;

class matrixdouble_new
{	
	public:
        // The default constructor
		matrixdouble_new();
        // General constructor for an m-by-n matrix 
		matrixdouble_new (int rows, int cols);
        // The copy constructor
        matrixdouble_new (const matrixdouble_new& A);
        
        int matrix_size[2];
        
        // Operators
        // Overloading the = operator for our matrix class
        matrixdouble_new& operator =(const matrixdouble_new &A);
        // Overloading the binary + operator for our matrix class
        friend matrixdouble_new operator +(const matrixdouble_new &A,
                                           const matrixdouble_new &B);
        // Overloading the binary - operator for our matrix class
        friend matrixdouble_new operator -(const matrixdouble_new &A,
                                           const matrixdouble_new &B);
        // Overloading the unary + operator for our matrix class
        friend matrixdouble_new operator +(const matrixdouble_new &A);
        // Overloading the unary - operator for our matrix class
        friend matrixdouble_new operator -(const matrixdouble_new &A);
        // Overloading the () operator
        double &operator()(int i, int j);
        // Overloading the * operator:
        // Multiplying a scalar by a matrix
        friend matrixdouble_new operator *(const double& a, const matrixdouble_new& A);
        // Multiplying a matrix by a scalar
        friend matrixdouble_new operator *(const matrixdouble_new& A, const double& a);
        // Multiplying a vector by a matrix
        friend matrixdouble_new operator *(const vectordouble& v, const matrixdouble_new& A);
        // Multiplying a matrix by a vector
        //friend matrixdouble_new operator *(const matrixdouble_new& A, const vectordouble& v);
        // Multiplying a matrix by a matrix
        friend matrixdouble_new operator *(const matrixdouble_new& A, const matrixdouble_new& B);
        // Dividing a matrix by a scalar
        friend matrixdouble_new operator /(const matrixdouble_new& A, const double& a);
        
   // functions     
        // The function 'eye'
        friend matrixdouble_new eye(int rows, int cols);
        // The function 'diag'
        //friend matrixdouble_new diag(vectordouble v, int k);
        
        // Function that returns the size of a matrix
        //friend vectordouble size(matrixdouble_new &A);
		
		//p2dArray operator+(const p2dArray&);
		//p2dArray& operator=(const p2dArray&);
        
        // Destructor
		~matrixdouble_new();
		// We define 'elem' as a pointer-to-a-pointer in order to dynamically allocate 
		// memory to our 2D array
		double **elem;
		int height;
		int width;
		
	private:
//		int height;
	//	int width; 
		//p2dArrayData **contents;
};

#endif 


and finally the error messages (again)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\byrnem6\My Documents\Oxford work\Courses\Cpp\Makefile.win"
Executing  make...
make.exe -f "C:\Documents and Settings\byrnem6\My Documents\Oxford work\Courses\Cpp\Makefile.win" all
g++.exe -c "Source files/matrixdouble_new.cpp" -o "Source files/matrixdouble_new.o" -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"C:/Dev-Cpp/include/c++/3.4.2/backward"  -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"C:/Dev-Cpp/include/c++/3.4.2"  -I"C:/Dev-Cpp/include"   

In file included from Source files/matrixdouble_new.cpp:5:
Source files/matrixdouble_new.h:48: error: expected `,' or `...' before '&' token
Source files/matrixdouble_new.h:48: error: ISO C++ forbids declaration of `vectordouble' with no type
Source files/matrixdouble_new.h:48: error: `matrixdouble_new operator*(int)' must have an argument of class or enumerated type

Source files/matrixdouble_new.cpp:6:28: vectordouble.hpp: No such file or directory
Source files/matrixdouble_new.cpp:207: error: expected `,' or `...' before '&' token
Source files/matrixdouble_new.cpp:208: error: ISO C++ forbids declaration of `vectordouble' with no type
Source files/matrixdouble_new.cpp:208: error: `matrixdouble_new operator*(int)' must have an argument of class or enumerated type
Source files/matrixdouble_new.cpp: In function `matrixdouble_new operator*(int)':
Source files/matrixdouble_new.cpp:212: error: expected `;' before "u"
Source files/matrixdouble_new.cpp:214: error: `u' undeclared (first use this function)

Source files/matrixdouble_new.cpp:214: error: (Each undeclared identifier is reported only once for each function it appears in.)
Source files/matrixdouble_new.cpp:218: error: `A' undeclared (first use this function)
Source files/matrixdouble_new.cpp:222: error: `v' undeclared (first use this function)
Source files/matrixdouble_new.cpp: At global scope:
Source files/matrixdouble_new.cpp:256: error: expected declaration before '}' token

make.exe: *** ["Source files/matrixdouble_new.o"] Error 1

Execution terminated 


Thanks again, this is really annoying and stalling my progress bigtime!

You have to forward declare vectordouble in matrixdouble_new.h

Ah, that works now. Thanks a lot jsmith, and everyone else!
Topic archived. No new replies allowed.