Declaring a variable as a "Class" datatype, without calling the "Class" constructor?
Forgive me if I'm just blatantly missing something, but I'm trying to make the transition from structs and c to classes and c+开发者_如何转开发+.
Heres what I'm trying to do:
A have a "Checkers" class and a "Board" class.
Now with structs, I could just create an array of Checkers in my "board.cpp" file by doing:
Checker checkers[2][12]
(0 and 1 for each side, 0-11 for each piece)
The problem is that with classes, doing the same declaration will attempt to call the "Checkers" constructor. I get this error: "error: no matching function for call to ‘Checker::Checker()’"
My Checker constructor deals with initializing an individual piece (like if it is on side 0 or 1, piece 0-11), so I didnt mean to call it there.
Is there a way to avoid this, or am I going about this the wrong way? Thanks.
EDIT: Or maybe I should just design the constructor to initialize an array of checkers? Can you even declare variables as a datatype of a class/object?
You can either create a default constructor or have an array of Checker
pointers and initialize them by dynamically allocation each Checker
in the Board
's constructor with the appropriate parameters. In the latter case, the constructor is not called until you allocate them.
Create a default constructor. Then use an initial function. I do recomend you use STL vector.
The problem is that with classes, doing the same declaration will attempt to call the "Checkers" constructor. I get this error: "error: no matching function for call to ‘Checker::Checker()’"
If you have defined parameterized constructors for your class(and not defined the default constructor), the default constructor won't be provided by the compiler. You have to write your version of default constructor as well.
Instead of using a two dimensional array, use vector of vectors.
std::vector<std::vector<Checker> > checkers;
You are creating an array of checkers to represent the individual checkers belonging to each side. The checkers require you to tell which side the checker is on, and which checker it is.
Why do you need to know which checker is which? If a player went out of the room, and someone swapped two of his checkers over, would he notice?
You can pass one constructor argument using array syntax as follows:
enum Side { White, Black };
class Checker
{
Side side ;
public:
Checker ( Side side ) : side(side) {
}
};
int main()
{
Checker white[12] = { White, White, White, White, White, White, White, White, White, White, White, White, };
Checker black[12] = { Black, Black, Black, Black, Black, Black, Black, Black, Black, Black, Black, Black, };
Checker* both[2] = { white, black };
return 0;
}
Multiple arguments require a copy constructor and would look like:
Checker white[12] = { Checker(White,0), Checker(White,1) ...
But I'd tend to just add the checkers to the board using just a few checker objects, representing White, Black, White Queen and Black Queen instead, unless there is a very good reason for identity to be tracked.
To answer this, I really need to see the definition of the "Checker" class. Here's a guess, though...
I think your Checker class defines non-default constructors, but doesn't have a default constructor. There is a default default constructor IYSWIM, but as soon as you define any constructor for yourself the compiler-provided implicit default constructor is disabled.
If you have...
class Checker
{
public:
Checker (int p) { ... };
};
You cannot use the default constructor, as needed for...
Checker checkers[2][12];
Instead, try...
class Checker
{
public:
Checker () { ... };
Checker (int p) { ... };
};
As for the advice to use std::vector, in this case I disagree. The array is fixes size, so there is no benefit to using std::vector - only extra complexity and other costs.
Keep your C-style array, but make it private (or at least protected) within a "Board" class is my advice.
精彩评论