So, here's the deal. My program has 2 classes, we'll call them Piece and Space, and one global pointer to an object of type Space.
Class Piece has nothing in the class requiring an object of class Space. Hooray, you can go first!
Class Space has a bunch of methods in it requiring objects of class Piece. I guess you go after class Piece, then!
Everything is aweso- wait... eh? No compiley?
Oh wait, class Piece uses the pointer of type Space. The pointer needs declared before Piece. But it also needs declared after Space, which is a direct reversal in my previous required order.
My question is this:
Can I declase class Space before class a without actually defining its methods or anything, a forward declaration of sorts? I've tried this:
class Space;
Space* pRofl;
class Piece
{zomg stuff!
}
...and methods, wow!...
class Space
{more stuf lulz
}
...and methods...
but it keeps telling me that Space is a struct, which i do not obviously want it to be. The infuriating thing is that it gets rid of all the errors about space not being first, but then generates more about redeclaring and defining my class and how it's a struct and how the compiler enjoys being a douchebag and stuff.
How can i use a forward declaration _successfully_, in this situation?
Posts
Anyway, I'm not really understanding what you're trying to do, but isn't it a bad idea to use global variables in a class? Classes are meant to be compartmentalized, the whole idea is that they're separate entities and have their own attributes and functions.
Look into inheritance classes and see if you can rearrange the classes that way so that one of them is a kind of the other. (Square -> Rectangle with even sides and Rectangle -> Polygon with 4 sides and 90 degree angles Polygon -> etc...)
It's hard out of context to give you much more than that.
I am attempting to program Chess from scratch.
I have objects of type Piece, along with inherited classes of type Piece like Pawn and Bishop, etc, but that all can be called Piece because of their type.
My board is a 2 dimensional array of pointers, pointers to class Space. Each space has data like its location and a pointer to whoever is on the space, and a bunch of methods such as clear space and such.
The only reason I made the board global is because it was simpler to do that than to include it in my setupBoard function, since it was at the bottom, and since Piece and Space end up using board[x][y], I end up having to declare it in advance.
I have just found this online:
"A forward declaration gives the compiler enough information to let you
create a pointer or a reference to an object of the forward declared
type, but not much more than that. It is NOT enough to allow you to
create objects of that type, and here you've defined the parameter to be
an object instead of a reference or pointer, so the compiler rejects the
code. "
In my code right now, in the Piece class, I use 3 methods which call for the board,
checkSpace (which will check to see if the supposed space is a valid move)
checkSpaceHostile (which will check to see if the supposed space is occupied by a hostile piece)
move (which will work with the board to empty out the space to move to, if occupied, and then move)
Forget having a class space. Simply define your board as x,y co-ordinates. Have a class piece. A piece has a co-ordinate that defines where it is on the board (Say, -1, -1 means it's dead and no longer on the board). All you sub types like say Pawn inherit from Piece. Each sub-type defines how it can move. Then when a move is being checked, search through the co-ordinate locations of each piece to make sure the move is legal.
Pretty inefficient, but I think the suggestion to have the piece contain x, y co-ordinates is a good one. I'd do that, but stick with the original idea to have a space class too. So all in all you'd end up with:
- a 2D array of instances of the space class (where each instance can contain a pointer to the piece occupying it, if needed)
- instances of the piece class, each containing an x, y index into the 2D space array
Each square is 30 x 30, so each piece sprite is 30 x 30. If a piece has a co-ordinate of 5,7, then display the piece at pixel location (5 x 30), (7 x 30). No need for a Space object.
Maybe i need a new class for these three methods only? That could work.
This is a console application, if that clears things up :-P
I'm too n00b to deal with graphics yet.
Hmm. I guess what he could do is define Class Piece, without giving it a Space attribute (Kinda odd, but it's friday and I'm winding down). Define Class Space as pointing to an object Piece. Define all your pieces inheriting from Class Piece and give each piece a Space.
Shouldn't be any reason that you should specifically call the piece itself during game play, you can just reference them through the spaces.
Edit: Damn you person that walked in my office and delayed my response by 5 minutes!
I think we are talking about two different things... I thought Nova's suggestion did not have piece directly pointing to objects of type space.
class piece
{
// index into the board array
int xPosition, yPosition;
...
}
class space
{
class piece *pCurrentPiece;
...
}
mainFunc
{
class space *boardArray [8][8];
...
}
My only problem now is a linker error, undefined reference to the checkMove(int x, int y, int player) function in my abstract Piece class, and I don't know what to look for about this error, since it's a linker one.
Piece* whitequeen = new Piece(arguments);
...before you try to look up any values associated with whitequeen.
Piece has a function called checkMove... this is really the only reason I even need the class, so that all the types of pieces, ie, queen, pawn, etc, can all be called one name and I dont have to know what type of piece it is before I try to check whether or not it can move to a certain space.
However, my linker error said there is an undefined reference to this function in my abstract Piece class.
iirc you should have Piece::checkMove(...) = 0;
virtual bool checkMove(int x, int y, int player);
definition:
not defined. Does not need to be defined as it is virtual and abstract, though it should be noted that I have tried averting this error by defining it as such:
bool Piece::checkMove(int x, int y, int player)
{
}
since there is no logic to checkMove for a generic piece.
I don't code in C++, but pure virtual methods can just be defined like this (I believe... look it up somewhere :P):
virtual bool checkMove(int x, int y, int player) = 0;
Then you don't have to implement them with an empty body.
You should probably just separate each class in their own file. I don't really understand what you're trying to do with that Space pointer... is pRofl the board?
What compiler are you using?
You have two classes, who need each other's definitions to exist properly, so
class A;
class B;
class A {
B* myFriendB;
//function declerations, etc
// if a function requires stuff from B, merely declare the function, without defining it, ie:
bool playWithB(int variable1);
// otherwise just do it normally:
void sayHi() { std::cout << "Hi!"; };
};
class B {
A* myFriendA;
int myNumber;
};
// after you've finished B, using the :: operator, you can now define the functions from A and B that you had toleave blank
bool A::playWithB(int variable1) {
std::cout << myFriendA->myNumber;
myFriendA->myNumber += variable1;
};