tags:

views:

267

answers:

5

I have a couple of cases of circular declaration in my class delaractions in my main (global) header.

#include <cstdlib>
#include <iostream>

using namespace std;


enum piece_t {BLACK, WHITE, EMPTY, WALL}; //wall is area out side of board (board array is 21x21 but only 19x19 is playable)
enum dir_t {ABOVE,BELOW,LEFT, RIGHT}; //shall i overload ! or - operatior? !LEFT==RIGHT?


struct nextPoint_t  //should be implimented with references, but need to practice pointer
{ 
  point_t* above;
  point_t* below;
  point_t* left;
  point_t* right;

};




class point_t
{
 private:
  piece_t mType; //what sort of point this is
  int mLiberties;
  nextPoint_t  mAdjacent; // points to adjacent points

  bool mLibertiesCounted; // keeps track of if liberties have been counted, for mCountLiberites() (sets), is reset by mUpdateLiberites(); 

  int mCountLiberties(); //counts this point's liberites, by calling count on mAdjacent points etc.
  void mSetPos(int xPos, int yPos, board_t theBoard); //sets up mAdjacent to point to adjacent points,
  void mSetStructureLiberties(int numLibs); // Sets this squares liberites then calls this on all adjacent squares 


 public:
  point_t ();//  parameterless constructor, for arrays
  void mSetUp(int xPos, int yPos, board_t theBoard);// sets up mType then calles setPos iFF not WALL type
  point_t (int xPos, int yPos, board_t theBoard); //constructor, takes it's position in the grid as a parameter

  void mUpdateLiberties(); // calles countLiberties then, updates liberites on whole of connected structure, by operating pon all conencted points



};

class board_t 
{
 private:
  point_t mArray [21][21];


 public:
  board_t(); //constructor, sets up board by operating on the point_t's

};

Don't worry about the comments there for my reading, I know what I mean.

I thought I could fix it with forward declarations, but they don't seem to work, it just thinks I'm redeifining the classes

+8  A: 

Alright, after considering the comments and doing a test on my own, the real answer : You must use forward declaration, no more. :)

#include <cstdlib>
#include <iostream>

class point_t;
class board_t;

/* Rest of the code stay the same */
Jodi
you could use references as well ... then you only need to change the function and not all code that references it ...
Goz
You're right Goz! It's better that way :)
Jodi
In a non-defining function declaration, parameter types are allowed to be incomplete. So this should be fine without pointers or references.
Johannes Schaub - litb
@Jodi: You are incorrect to say that you must use fwd decl. AND pointers/refs. Its true that forward declarations are needed, but method declarations don't have to have pointers/refs.
quamrana
@Jodi: Please remove the `using namespace std;` statement. Its not even needed in the OP's question.
quamrana
A: 
#include <cstdlib>
#include <iostream>

enum piece_t {BLACK, WHITE, EMPTY, WALL}; //wall is area out side of board (board array is 21x21 but only 19x19 is playable)
enum dir_t {ABOVE,BELOW,LEFT, RIGHT}; //shall i overload ! or - operatior? !LEFT==RIGHT?

class point_t;

struct nextPoint_t  //should be implimented with references, but need to practice pointer
{ 
  point_t* above;
  point_t* below;
  point_t* left;
  point_t* right;

};


class board_t;

class point_t
{
 private:
  piece_t mType; //what sort of point this is
  int mLiberties;
  nextPoint_t  mAdjacent; // points to adjacent points

  bool mLibertiesCounted; // keeps track of if liberties have been counted, for mCountLiberites() (sets), is reset by mUpdateLiberites(); 

  int mCountLiberties(); //counts this point's liberites, by calling count on mAdjacent points etc.
  void mSetPos(int xPos, int yPos, const board_&t theBoard); //sets up mAdjacent to point to adjacent points,
  void mSetStructureLiberties(int numLibs); // Sets this squares liberites then calls this on all adjacent squares 


 public:
  point_t ();//  parameterless constructor, for arrays
  void mSetUp(int xPos, int yPos, const board_t& theBoard);// sets up mType then calles setPos iFF not WALL type
  point_t (int xPos, int yPos, const board_t& theBoard); //constructor, takes it's position in the grid as a parameter

  void mUpdateLiberties(); // calles countLiberties then, updates liberites on whole of connected structure, by operating pon all conencted points



};

class board_t 
{
 private:
  point_t mArray [21][21];


 public:
  board_t(); //constructor, sets up board by operating on the point_t's

};
Goz
@Goz: Please remove the `using namespace std;` statement. Its not even needed in the OP's question.
quamrana
edited my post.
Goz
+2  A: 

if you write before your struct

class point_t;

that should do the trick.

Although I am not quite sure why your organize your class like that. You already have an array mArray in your board so there is no real need to have pointers to adjacent points inside each point_t.

EDIT: as the other poster said before you need to use pointers.

Anders K.
i agree, you can easily find youself in a situation where you have inconsistent data. adjacency should be a calculated value. plus it'll save memory ;)
dharga
How could I end up with inconsistant data?it's the same memory just accessed a different way.I need check what is adjacent multiple times (read 100+ of times per function call) recalcalating would cost time.I could leave this up the the optimiser, i guess.also, at the moment no point_t knows where it is in the array; though that could eaisily be fixed.but wouldn't using the array, (which is part of board_t) be bad practice, as all the functions for dealing with point_t relate to other point_t objects. (really a point_t object has no meaning execpt it's relationship with others)
Oxinabox
+1  A: 

Just add this above struct nextPoint_t

enum piece_t {BLACK, WHITE, EMPTY, WALL};
enum dir_t {ABOVE,BELOW,LEFT, RIGHT}; 

class point_t;
class board_t;

struct nextPoint_t
{ 
  point_t* above;
  point_t* below;
  point_t* left;
  point_t* right;
};

And change any reference to a board_t to a board_t*

void mSetUp(int xPos, int yPos, board_t* theBoard);
dharga
+3  A: 

The forward references in your code seems to be to board_t and point_t, which is resolved by forward declaring them.

Since you reference board_t in member function declarations of point_t, you cannot define the member functions right away in point_t. Their definitions have to appear after board_t is defined. So you have to either move the definition of the functions into the cpp file, or you have to move their definition in the header after definition of board_t whichever suites you more. point_t is only used as a pointee type in nextPoint_t, so we don't have the same problem for it here:

class point_t; // used by nextPoint_t
class board_t; // used by point_t

struct nextPoint_t  //should be implimented with references, but need to practice pointer
{ 
  point_t* above; // goes without problems - doesn't need definition of point_t
  point_t* below;
  point_t* left;
  point_t* right;
};

class point_t
{
 private:
  piece_t mType;
  int mLiberties;
  nextPoint_t  mAdjacent;
  bool mLibertiesCounted;

  int mCountLiberties();
  void mSetPos(int xPos, int yPos, board_t theBoard);
  void mSetStructureLiberties(int numLibs); 

 public:
  point_t ();
  void mSetUp(int xPos, int yPos, board_t theBoard);
  point_t (int xPos, int yPos, board_t theBoard);

  void mUpdateLiberties(); 
};

class board_t 
{
 private:
  point_t mArray [21][21];

 public:
  board_t();     
};

Definition at the end of the header looks like

// define it either inline in the header, or non-inline in a cpp file
inline void point_t::mSetPos(int xPos, int yPos, board_t theBoard) {
  /* some work... */
}

// same for mSetUp...

Nonetheless i would recommend you to use const references to pass the board to point_t's member functions, but this is not a requirement for your code to work. Declarations go fine with incomplete parameter types.

Johannes Schaub - litb