user-type operator definition and multiple classes / source files

G

Gerard Kramer

Hello,

There is a slight problem with operator overloading in a program I
attempt to start practising C++. It is a basic (not very original) game
of life simulator. It uses two classes: LifeGeneration and LifeHistory.
Declarations are given by:

// Contents of file LifeGeneration.h

#ifndef LIFEGENERATION_H
#define LIFEGENERATION_H

namespace life {

class LifeGeneration {

private:

int generation[ROW_DIM][COL_DIM];

unsigned mod(int, unsigned);
unsigned int countNn(int, int);
int alive(int, int);

public:

LifeGeneration();
void setCell(int, int, int);
void nextGeneration();
bool operator == (const LifeGeneration &);

};

}

#endif

and:

// Contents of file LifeHistory.h

#ifndef LIFEHISTORY_H
#define LIFEHISTORY_H

namespace life {

class LifeHistory {

private:

LifeGeneration history[MAX_GENERATIONS];
unsigned n; // Generation counter

public:

LifeHistory();
unsigned storeGeneration(LifeGeneration);
unsigned getLength();
unsigned isPeriodic();

};

}

#endif

There is a problem with the following implementation:

// Contents of file LifeHistory.cpp

#include "parameters.h" // Contains definitions of constants
#include "LifeGeneration.h"
#include "LifeHistory.h"

namespace life {

// (...)

unsigned LifeHistory::isPeriodic() {
// Tests whether evolution is periodic with period > 0.
// Returns zero for a-periodicity.
for (unsigned i = 0; i < n; i++)
if (history == history)
return i;
return 0;
}

}

The test-for-equality operator used in the isPeriodic() function is
defined as:

// Contents of file LifeGeneration.cpp

#include "parameters.h"
#include "LifeGeneration.h"

namespace life {

// (...)

bool LifeGeneration::eek:perator == (const LifeGeneration & g) {
bool eq;
for (int m = 0; m < ROW_DIM; m++)
for (int n = 0; n < COL_DIM; n++)
eq = generation[m][n] == g.generation[m][n];
return eq;
}

}

When I perform a compilation to obtain a module LifeHistory.o, I get
complaints:

$ g++ -c LifeHistory.cpp
LifeHistory.cpp: In member function `unsigned int
life::LifeHistory::isPeriodic()':
LifeHistory.cpp:31: error: no match for 'operator==' in '
this->life::LifeHistory::history == this->life::LifeHistory::history'
LifeGeneration.h:28: error: candidates are: bool
life::LifeGeneration::eek:perator==(const life::LifeGeneration&)

Resources I consulted are not very helpful because they contain little
discussion regarding the use of multiple source files. I must be missing
something very simple, but I can't figure out what it is. Could someone
give me a hint and/or constructive criticism? I'm grateful in advance.

Regards,
Gerard.
 
M

Markus Schoder

Gerard said:
Hello,

There is a slight problem with operator overloading in a program I
attempt to start practising C++. It is a basic (not very original) game
of life simulator. It uses two classes: LifeGeneration and LifeHistory.
Declarations are given by:

// Contents of file LifeGeneration.h

#ifndef LIFEGENERATION_H
#define LIFEGENERATION_H

namespace life {

class LifeGeneration {

private:

int generation[ROW_DIM][COL_DIM];

unsigned mod(int, unsigned);
unsigned int countNn(int, int);
int alive(int, int);

public:

LifeGeneration();
void setCell(int, int, int);
void nextGeneration();
bool operator == (const LifeGeneration &);

};

}

#endif

and:

// Contents of file LifeHistory.h

#ifndef LIFEHISTORY_H
#define LIFEHISTORY_H

namespace life {

class LifeHistory {

private:

LifeGeneration history[MAX_GENERATIONS];
unsigned n; // Generation counter

public:

LifeHistory();
unsigned storeGeneration(LifeGeneration);
unsigned getLength();
unsigned isPeriodic();

};

}

#endif

There is a problem with the following implementation:

// Contents of file LifeHistory.cpp

#include "parameters.h" // Contains definitions of constants
#include "LifeGeneration.h"
#include "LifeHistory.h"

namespace life {

// (...)

unsigned LifeHistory::isPeriodic() {
// Tests whether evolution is periodic with period > 0.
// Returns zero for a-periodicity.
for (unsigned i = 0; i < n; i++)
if (history == history)


history is an array of LifeGeneration objects but you need a plain
LifeGeneration object. It should probably be something like

if (history == history[n])

generally speaking the second operand should be your current generation.
return i;

This can return 0 so either return say i+1 here or choose for instance
UINT_MAX to indicate a-periodicity.
return 0;
}

}

The test-for-equality operator used in the isPeriodic() function is
defined as:

// Contents of file LifeGeneration.cpp

#include "parameters.h"
#include "LifeGeneration.h"

namespace life {

// (...)

bool LifeGeneration::eek:perator == (const LifeGeneration & g) {
bool eq;
for (int m = 0; m < ROW_DIM; m++)
for (int n = 0; n < COL_DIM; n++)
eq = generation[m][n] == g.generation[m][n];
return eq;
}
}

This function looks odd since eq captures just the result of the very last
comparison. You probably want

bool LifeGeneration::eek:perator == (const LifeGeneration & g) {
for (int m = 0; m < ROW_DIM; m++)
for (int n = 0; n < COL_DIM; n++)
if (generation[m][n] != g.generation[m][n])
return false;
return true;
}
 
G

Gerard Kramer

Thank you for your to-the-point reply. I made the stupid mistake of
assuming that history is equivalent to history[0] while in fact it is
equivalent to &history[0].

The other remarks were also very right.

Regards,
G.

Markus said:
Gerard said:
Hello,

There is a slight problem with operator overloading in a program I
attempt to start practising C++. It is a basic (not very original) game
of life simulator. It uses two classes: LifeGeneration and LifeHistory.
Declarations are given by:

// Contents of file LifeGeneration.h

#ifndef LIFEGENERATION_H
#define LIFEGENERATION_H

namespace life {

class LifeGeneration {

private:

int generation[ROW_DIM][COL_DIM];

unsigned mod(int, unsigned);
unsigned int countNn(int, int);
int alive(int, int);

public:

LifeGeneration();
void setCell(int, int, int);
void nextGeneration();
bool operator == (const LifeGeneration &);

};

}

#endif

and:

// Contents of file LifeHistory.h

#ifndef LIFEHISTORY_H
#define LIFEHISTORY_H

namespace life {

class LifeHistory {

private:

LifeGeneration history[MAX_GENERATIONS];
unsigned n; // Generation counter

public:

LifeHistory();
unsigned storeGeneration(LifeGeneration);
unsigned getLength();
unsigned isPeriodic();

};

}

#endif

There is a problem with the following implementation:

// Contents of file LifeHistory.cpp

#include "parameters.h" // Contains definitions of constants
#include "LifeGeneration.h"
#include "LifeHistory.h"

namespace life {

// (...)

unsigned LifeHistory::isPeriodic() {
// Tests whether evolution is periodic with period > 0.
// Returns zero for a-periodicity.
for (unsigned i = 0; i < n; i++)
if (history == history)


history is an array of LifeGeneration objects but you need a plain
LifeGeneration object. It should probably be something like

if (history == history[n])

generally speaking the second operand should be your current generation.
return i;

This can return 0 so either return say i+1 here or choose for instance
UINT_MAX to indicate a-periodicity.
return 0;
}

}

The test-for-equality operator used in the isPeriodic() function is
defined as:

// Contents of file LifeGeneration.cpp

#include "parameters.h"
#include "LifeGeneration.h"

namespace life {

// (...)

bool LifeGeneration::eek:perator == (const LifeGeneration & g) {
bool eq;
for (int m = 0; m < ROW_DIM; m++)
for (int n = 0; n < COL_DIM; n++)
eq = generation[m][n] == g.generation[m][n];
return eq;
}
}

This function looks odd since eq captures just the result of the very last
comparison. You probably want

bool LifeGeneration::eek:perator == (const LifeGeneration & g) {
for (int m = 0; m < ROW_DIM; m++)
for (int n = 0; n < COL_DIM; n++)
if (generation[m][n] != g.generation[m][n])
return false;
return true;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top