Jump to content
  • Advertisement
Sign in to follow this  
c4c0d3m0n

Operator overloading

This topic is 3960 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wasn't too sucessful in finding information on this topic... This is my class:
/**
  * matrix.h
  * Follow the white rabbit
  *
**/

class Matrix {
private:
    std::vector<std::vector<int> > matrix;
    int sizex;
    int sizey;
    int overvalue;

public:
    // Default constructor
    Matrix() {}

    // Fancy constructor, create a matrix full of 0
    Matrix( int width, int height, int max ) {
        sizex = width;
        sizey = height;
        overvalue = max + 1;

        std::vector<int> v( sizey, 0 );
        std::vector<std::vector<int> > vx( sizex, v );
        matrix = vx;
        // Future usage of matrix: matrix[x][y]
    }

    // Randomize the matrix
    void Randomize( int min, int max ) {
        for( int i = 0; i < sizey; i++ ) {
            for( int j = 0; j < sizex; j++ ) {
                matrix[j] = rand() %((max %overvalue) - min) + min;
            }
        }
    }

    void FlipSquareCW() {
        if( sizex == sizey ) {
            Matrix tmp( sizex, sizey, overvalue - 1 );
            tmp = matrix;

            for( int i = 0; i < sizey; i++ ) {
                for( int j = 0; j < sizex; j++ ) {
                    matrix[j] = tmp[(sizex - 1) - j]
                }
            }
        }
    }

    // Set a cell in the matrix
    void SetXYI( int x, int y, int i ) {
        matrix[x%sizex][y%sizey] = i %overvalue;
    }

    // Get the value of a cell in the matrix
    int GetXY( int x, int y ) {
        return matrix[x%sizex][y%sizey];
    }


};


/**
  * End of matrix.h
  *
**/

In the function FlipSquareCW(), I want to use = beteen two Matrix. How can I archieve this?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by c4c0d3m0n
In the function FlipSquareCW(), I want to use = beteen two Matrix. How can I archieve this?


Nothing!

The compiler will automatically give you an operator= that works by directly assigning all of the member variables. In this case, I imagine that is what you want (in other cases it won't be). If you were to implement the default behaviour yourself, it would look like this:

Matrix operator=(Matrix lhs, Matrix rhs)
{
lhs.matrix = rhs.matrix;
lhs.sizex = rhs.sizex;
lhs.sizey = rhs.sizey;
lhs.overvalue = rhs.overvalue;

return lhs;
}


You would also have to make this function a friend of the Matrix class. You could also write it as a member function, but I prefer the free function version.

HTH

Share this post


Link to post
Share on other sites
That is my problem, my compiler doesn't automaticly do this. I get this compiler error:

matrix.h: In member function `void Matrix::FlipSquareCW()':
matrix.h:42: error: no match for 'operator=' in 'tmp = ((Matrix*)this)->Matrix::matrix'
matrix.h:7: note: candidates are: Matrix& Matrix::operator=(const Matrix&)
matrix.h:46: error: no match for 'operator[]' in 'tmp'

Share this post


Link to post
Share on other sites
That is because "matrix" is of type std::vector< std::vector<int> >.

You would need "temp = *this;" or better "Matrix temp = *this;".

Also note that the vectors hold their size internally, you can find the size of a vector using std::vector<>::size(). For efficiency, most people would write a Matrix class that uses a single dimensional vector and treats it as a two dimensional array.

A simple formula to turn a x,y pair into a single dimensional index is:

int index = x + sizey * y;


It is also common to overload operator() to take two integer arguments and return a reference (a const and non const version) to make the interface a little friendlier:

class Matrix
{
std::vector< std::vector< int > > matrix;
public:

int &operator()( int x, int y )
{
return matrix[x][y];
}

const int &operator()( int x, int y ) const
{
return matrix[x][y];
}
};

void example( const Matrix &matrix )
{
// ...
int i = matrix(x,y);
}

Share this post


Link to post
Share on other sites
matrix is a vector of a vector of ints. tmp is a Matrix. You can't convert from one to the other, only from the same type. I'm unsure of the best way to tell you what you want to do because I'm not really sure what you want to do. There is probably a better way, but for now I THINK what you want is to make tmp the same type as matrix like so:

vector<vector<int> > tmp

Share this post


Link to post
Share on other sites
I realized my mistake soon after my post, thanks for the quick replay though. I am going to look into this operator overloading a little more. This is how my class looks now:

/**
* matrix.h
* Follow the white rabbit
*
**/


class Matrix {
private:
std::vector<std::vector<int> > matrix;
int sizex;
int sizey;
int overvalue;

public:
// Default constructor
Matrix() {}

// Fancy constructor, create a matrix full of 0
Matrix( int width, int height, int max ) {
sizex = width;
sizey = height;
overvalue = max + 1;

std::vector<int> v( sizey, 0 );
std::vector<std::vector<int> > vx( sizex, v );
matrix = vx;
// Future usage of matrix: matrix[x][y]
}

// Randomize the matrix
void Randomize( int min, int max ) {
for( int i = 0; i < sizey; i++ ) {
for( int j = 0; j < sizex; j++ ) {
matrix[j] = rand() %((max %overvalue) - min) + min;
}
}
}

void FlipSquareCW() {
if( sizex == sizey ) {
Matrix tmp( sizex, sizey, overvalue - 1 );

for( int i = 0; i < sizey; i++ ) {
for( int j = 0; j < sizex; j++ ) {
tmp.SetXYI( j, i, matrix[j] );
}
}

for( int i = 0; i < sizey; i++ ) {
for( int j = 0; j < sizex; j++ ) {
matrix[j] = tmp.GetXY( i, sizex - 1 - j );
}
}
}
}

// Set a cell in the matrix
void SetXYI( int x, int y, int i ) {
matrix[x%sizex][y%sizey] = i %overvalue;
}

// Get the value of a cell in the matrix
int GetXY( int x, int y ) {
return matrix[x%sizex][y%sizey];
}


};


/**
* End of matrix.h
*
**/


Share this post


Link to post
Share on other sites
Your constructor can be written as:
Matrix(int width, int height, int max) :
sizex(width),
sizey(height),
overvalue(max + 1),
matrix(sizex, std::vector<int>(sizey, 0))
{
}
However, I'd recommend taking the advice offered previously and storing the data in a single 1-d array.

I'm also curious what the 'overflow' value is for, and what the overall purpose of the matrix class is (so far, except for the overflow stuff, it looks like you could just as easily use boost::multi_array...).

Share this post


Link to post
Share on other sites
Wow, that's neat! I shall rewrite all my constructors like that.

I don't quite see how that 1-d array would work, but it's late, and I'm probably just too deaf to see it.

The overflow value is to keep stuff in bounds. I don't even know why I put it there anymore. I use it instead of a maximum var, because it's easier to use modulo like this.

This Matrix has several uses. One use is to hold the Tetris-field (a 10*20 array of the values 0-8) Another use is to hold the Tetrominoes (a 4*4 array of 0-1). The Tetrominoe array is a bool-array pretty much, that just holds the form. The type of block (the colour) is defined elsewhere.

I don't know much about boost, so I didn't think of using it.

Share this post


Link to post
Share on other sites
rip-off gave an example earlier of how to index the 1-d array correctly (and also of how to overload operator()() for the purpose of accessing the matrix elements).

Really though, it seems like multi_array would be ideal for what you're describing (from what I've seen, the 'overflow' stuff in your matrix class doesn't look that useful).

Anyway, I'd check out some of the Boost libs if I were you; although implementing this sort of thing yourself can be a good learning experience, using proven third-party solutions is usually a win in terms of development time and quality of code.

Share this post


Link to post
Share on other sites
Quote:
Original post by c4c0d3m0n
Wow, that's neat! I shall rewrite all my constructors like that.


Argh, please don't re-write all of them :)
There are cases when you don't want initializer lists necessarily. The C++ FAQ Lite does a better job of explaining why you might not always want to use them.

~Shiny

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!