Overloading the [] operator for 2 dimensional arrays

Hello,
I created a class Matrix and I'm trying to overloading the [] Operator.
I'm using following two files:

1.) net.cpp:
#include "net.hpp"
#include <iostream>
#include <cmath>

using std::cout;

Matrix::Matrix() {
dimZeilen = 0;
dimSpalten = 0;
coeff = NULL;
}
Matrix::Matrix(int dimZeilen, int dimSpalten) {
int spalte = 0;
int zeile = 0;
this->dimZeilen = dimZeilen;
this->dimSpalten = dimSpalten;
coeff = (double*) malloc(dimZeilen*dimSpalten*sizeof(double));
for (zeile=0; zeile<dimZeilen; ++zeile) {
for (spalte=0; spalte<dimSpalten; ++spalte) {
coeff[zeile,spalte] = 0;
}
}
}
Matrix::Matrix(int dimZeilen, int dimSpalten, double init) {
int spalte = 0;
int zeile = 0;
this->dimZeilen = dimZeilen;
this->dimSpalten = dimSpalten;
coeff = (double*) malloc(dimZeilen*dimSpalten*sizeof(double));
for (zeile=0; zeile<dimZeilen; ++zeile) {
for (spalte=0; spalte<dimSpalten; ++spalte) {
coeff[zeile,spalte] = init;
}
}
}
Matrix::Matrix(const Matrix& rhs) {
dimZeilen = rhs.getDimZeilen();
dimSpalten = rhs.getDimSpalten();
coeff = new double[dimZeilen*dimSpalten];
for (int zeile=0; zeile<dimZeilen; ++zeile) {
for (int spalte=0; spalte<dimSpalten; ++spalte) {
coeff[zeile,spalte] = rhs[zeile,spalte];
}
}
cout << "Kopierkonstruktor\n";
}
Matrix::~Matrix() {
if (dimZeilen > 0 || dimSpalten > 0) {
free(coeff);
}
// just for demonstration purposes
cout << "free matrix, size " << dimZeilen*dimSpalten << "\n";
}
Matrix& Matrix::operator=(const Matrix& rhs) {
dimZeilen = rhs.getDimZeilen();
dimSpalten = rhs.getDimSpalten();
delete[] coeff;
coeff = new double[dimZeilen*dimSpalten];
for (int zeile=0; zeile<dimZeilen; ++zeile) {
for (int spalte=0; spalte<dimSpalten; ++spalte) {
coeff[zeile,spalte] = rhs[zeile,spalte];
}
}
return *this;
}
int Matrix::getDimZeilen() const {
return dimZeilen;
}
int Matrix::getDimSpalten() const {
return dimSpalten;
}
const double& Matrix::operator[](int g), (int k) const {
assert(g>=0 && g<dimZeilen);
assert(k>=0 && k<dimSpalten);
return coeff[g,k];
}
double& Matrix::operator[](int g), (int k) {
assert(g>=0 && g<dimZeilen);
assert(k>=0 && k<dimSpalten);
return coeff[g,k];
}
void Matrix::set(int zeile, int spalte, double value) {
assert(zeile>=0 && zeile<dimZeilen);
assert(spalte>=0 && spalte<dimSpalten);
coeff[zeile,spalte] = value;
}
double Matrix::get(int zeile, int spalte) const {
assert(zeile>=0 && zeile<dimZeilen);
assert(spalte>=0 && spalte<dimSpalten);
return coeff[zeile,spalte];
}

***************************************************************************

2.) net.hpp:
#ifndef NET
#define NET

#include <cmath>
#include <cstdlib>
#include <cassert>

class Matrix {
private:
int dimZeilen;
int dimSpalten;
double* coeff;

public:
Matrix();
Matrix(int dimZeilen, int dimSpalten);
Matrix(int dimZeilen, int dimSpalten, double init);
Matrix(const Matrix& rhs);
Matrix& operator=(const Matrix& rhs);
~Matrix();
int getDimZeilen() const;
int getDimSpalten() const;
const double& operator[](int g), (int k) const;
double& operator[](int g), (int k);
void set(int zeile, int spalte, double value);
double get(int zeile, int spalte) const;

};

***************************************************************************

and if I compile the files with g++ -c net.cpp I always get the errors:

In file included from net.cpp:1:0:
net.hpp:65:36: error: expected unqualified-id before ‘int’
const double& operator[](int g), (int k) const;
^
net.hpp:65:36: error: expected ‘)’ before ‘int’
net.hpp:67:10: error: ‘double& Matrix::operator[](int)’ cannot be overloaded
double& operator[](int g), (int k);
^
net.hpp:65:16: error: with ‘const double& Matrix::operator[](int)’
const double& operator[](int g), (int k) const;
^
net.hpp:67:30: error: expected unqualified-id before ‘int’
double& operator[](int g), (int k);
^
net.hpp:67:30: error: expected ‘)’ before ‘int’
net.cpp: In copy constructor ‘Matrix::Matrix(const Matrix&)’:
net.cpp:106:42: error: passing ‘const Matrix’ as ‘this’ argument of ‘const double& Matrix::operator[](int)’ discards qualifiers [-fpermissive]
coeff[zeile,spalte] = rhs[zeile,spalte];
^
net.cpp: In member function ‘Matrix& Matrix::operator=(const Matrix&)’:
net.cpp:125:42: error: passing ‘const Matrix’ as ‘this’ argument of ‘const double& Matrix::operator[](int)’ discards qualifiers [-fpermissive]
coeff[zeile,spalte] = rhs[zeile,spalte];
^
net.cpp: At global scope:
net.cpp:136:39: error: declaration of ‘const double& Matrix::operator[](int)’ outside of class is not definition [-fpermissive]
const double& Matrix::operator[](int g), (int k) const {
^
net.cpp:136:43: error: expected unqualified-id before ‘int’
const double& Matrix::operator[](int g), (int k) const {
^
net.cpp:136:43: error: expected ‘)’ before ‘int’
net.cpp:141:9: error: prototype for ‘double& Matrix::operator[](int)’ does not match any in class ‘Matrix’
double& Matrix::operator[](int g), (int k) {
^
net.cpp:136:15: error: candidate is: const double& Matrix::operator[](int)
const double& Matrix::operator[](int g), (int k) const {
^
net.cpp:141:37: error: expected unqualified-id before ‘int’
double& Matrix::operator[](int g), (int k) {
^
net.cpp:141:37: error: expected ‘)’ before ‘int’

*****************************************************************************

I tried some things to resolve the error but it doesn't work because I don't know how is the syntax for the input parameters of a 2 dimensional array.

Can someone resolve this problem?
An operator[]() overload can only take exactly one parameter.
Here's an idea:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Indexer;

class Matrix{
public:
    Indexer operator[](int i);
    void at(int i, int j){
        std::cout << "Accessing matrix[" << i << "][" << j << "]\n";
    }
};

class Indexer{
    Matrix *m;
    int i;
public:
    Indexer(Matrix *m, int i): m(m), i(i){}
    void operator[](int j){
        this->m->at(this->i, j);
    }
};

Indexer Matrix::operator[](int i){
    return Indexer(this, i);
}
Ah okay.
I'll think about your idea and thank you for your quick answer :)
Think of a 2D array like this, you're accessing an entirely different element.

For instance:
1
2
3
4
5
int** arr;
arr = new int[5];
arr[0] = new int[5];

arr[0][0] = 10;


So in effect, it's just passing you over to the next overloaded operator. Hence why you can overload a single index of brackets.
All that said... you shouldn't be doing it that way.

Yes, I know people like the pretty "I'm an array" syntax.

Don't.

Write an accessor function that takes two indices as argument:

1
2
3
4
5
6
7
8
9
class Matrix
{
  ...

  double& operator () ( int z, int s ) { return coeff[ z*dimSpalten + s ]; }
  const double& operator () ( int z, int s ) const { return coeff[ z*dimSpalten + s ]; }

  ...
};

Now use it normally:

1
2
3
4
Matrix m(10,10);
m(0,2) = 3.14;
cout << m(3,7) << "\n";
...

Hope this helps.
Hey, thank you for your help. I changed my code and it works.
Thank you :)
Topic archived. No new replies allowed.