How do I define static array in .cpp file of my class - c++

I know there is many question talks about static function and variable but I can't find the one that explain me how do things like this:
board.h
class board:public QGraphicsPixmapItem
{
public:
board();
static basedice *gamepos[8][8];
};
and I want to defined my array like this:
board.cpp
board::board()
{
for (int i=0;i<8;i++)
{
for (int j=0;j<8;j++)
{
gamepos[i][j]=NULL;
}
}
}
And I have one more question,Is that a right way to use an array in many classes something like global array... for example in chess game for holding postion of my pieces?
Sorry for my bad english.

If you really want the gamepos array to be static you can declare a static method in class Board that will initialize the array.
Then you call this method from outside the class.
int main() {
Board * myboard = new Board();
Board::initGamepos();
}
However looking at your code and what you want to do (which is reinitialize the gamepos array everytime you create a new Board instance, it is clear that you do NOT want gamepos to be static.
1 board <=> 1 gamepos array : that is not the mark of a static member, that is the mark of a standard member.

Static variables are automatically initialized to zero/false/null, so you don't need to initialize the array.
Anyway, you should not be reinitializing a static variable from your instance constructor as that will produce funny results.

Related

Declaring Const variables

I plan to use an array ... myarray(row,col)
I want to make both row =3, and col=3
This array will be in
myclass{
private:
myarray[row][col];
public:
void myfunction(); //will use the value of Row & Col
(Don't worry bout this function, I only put it here
so you know the variables will be accessed)
}
Q. I am thinking I should declare both row & col as const variables, but I am not sure if they should be declared in or out of the class. They will be accessed by other class functions. I am putting their definition in my cpp file. Anyone's advice is greatly appreciated - Thanks in Advance
This is completely up to you. It depends how those variables are used in your program. My personal preference is to make them class members. The reason is to wrap them in the class name space. This way you you can have multiple 'col' and 'row' constants within different classes.
In your case, you must declare them as static within the class. The reason is that you use them in a an array size declaration.
For example,
class myclass {
public:
static const int col = 3, row = 4;
int myarray[row][col];
};
myclass mc1 = new myclass;
... myclass::col ... mc1->row ...
You can make them private, if you do not need them outside the class.
There is nothing wrong in making them global. It could be easier to access the constants in some cases. However, it might be more difficult to understand your program by the fellow programmers.
You could use a global MACRO to define row and col like
#DEFINE COL 3
#DEFINE ROW 3
and then cal use COL and ROW anywhere in the code

Why must my global variable be declared as a pointer?

When compiling my C++ program I receive no errors, however within unordered_map the hash function fails, attempting to mod by 0. (Line 345 of hashtable_policy.h of stl)
I've found a fix, but don't know why I'm having the problem to begin with.
My struct looks like this, (Sorry for the specific code.)
struct Player {
private:
Entity& entity = entityManager->create();
public:
Player() {
entity.addComponent(new PositionComponent(0, 0)); // Add component uses the unordered map.
}
};
Player playerOne; // Error perpetuates through constructor.
However, if I declare playerOne as a pointer, like so:
Player* playerOne;
and then call:
playerOne = new Player();
I do not have any issues.
I've been searching - with no success. What could I be doing wrong?
When you use a Player as a global, you've no idea if the entityManager (presumably another global) has been initialised yet - the order of initialisation of globals isn't defined.
When you use the pointer and initialise it with new (in main(), I presume), all the globals have been created by then, so the code works.
This highlights one of the reasons why global variables are a bad idea.

Calling function to return private variable from class not working

So I am making a small game in C++ and I have run across a problem. I have a class called player inside my player.h file, and inside this class I have a public function called getPotion(). I also have a private static variable called potion. I have the exact same thing for the players health, and the getHealth() function returns the private static int playerHealth perfectly. But for apparently no reason, the getPotion function doesn't return the potion. I get an error instead. I've also included the header file in all my other files.
Here's the code:
(Sorry, I don't know how to insert code, so I have to write it out)
player.h (the code that I'm having trouble with):
class Player{
private:
static int potions;
public:
int getPotions();
}
player.cpp (again the code I have trouble with):
int Player::potions;
int Player::getPotions(){
Player player;
return player.potions;
}
I have probably left out some bits of code like return and such, but that's because I have a small amount of time to ask this question, so I put the parts that related to my problem.
First off, you are trying to return a static member of a class as if it were instantiated member of the object. Static members are referred to by Class::member, not object.member.
Second, I don't think you want potions to be static. Static members are shared between all objects of the class. So if player A has 100 health potions, then player B would have the same 100 health potions.
Third, you declare Player::potions at the top of your .cpp file. I don't think that's what you want. The potions member was already declared in your .h file.
player.h:
class Player
{
private:
int potions;
public:
int getPotions();
};
player.cpp:
int Player::getPotions()
{
return potions;
}
If you DID want potions to be static, then change it to:
return Player::potions;
Try changing
Player player;
return player.potions;
to simply
return potions;
You're creating a new player and returning that object's potions, not the potions of the "this" object.

Structure of program

I have few files:
main.cpp:
int main{
...
while(1){
...
draw();
...
}
...
return 0;
}
and draw.cpp:
I want to see objects and all manipulations here.
I cant make objects local to draw(), because draw() is inside loop,
so I will get many object constructor/destructor calls - so they are global. Also
I ve made init block to prevent unnecessary calls/assignments
draw.cpp:
Object A, B;
int initialized = 0;
void draw(){
if(!initialized){
A.initialization;
B.initialization;
initialized = 1;
}
A.move(1,1);
B.rotate(45);
}
It works, but Im looking for better way to organize my code
Added:
Thanks for answers, looks like I have to read something about pattern designs
Here's steps to make it work better:
Add a struct containing all your objects near main().
pass it to draw(MyStruct &s); via reference parameter.
you're done.
Option 1
Define a new Class called Draw and put the attributes into it. You need to modify main and draw files for this. With this you can avoid declaring anything global
Option 2
Define a class within draw.cpp called draw and add your current global variables as static member variables. Initialize and use them using static functions. With this you dont have to change main.
This design technique is called Singleton (one of the design patterns)
Example code
draw.cpp
class Draw
{
public:
object A, B;
static void init()
{
// init A
// init B
isInitialized = 1;
}
static int isInitialized;
static Object & getA()
{
if(isInitialized == 0)
{
init();
}
return A;
}
// similarly B
};

How can I make an instant-dependant static variabe in a class method?

I have a function in a class the more or less works like so:
class Player {
private:
Object* minions[16]
public:
void Summon(Object* obj);
};
Player::Summon(Object* obj) {
static int i = 0;
if (i == 16)
return;
minions[i] = obj;
i++;
}
The problem arise when trying to use more than one player, like so:
Player playerone;
Player playerthree;
playerone.Summon(new Object("o1"));
playerthree.Summon(new Object("o2"));
o1 is located in playerone.minions[0], as is expected, however, o2 is located in playerthree.minions[1], the Summon() function using the same i variable. Is there a way to make the Summon() function use a static i variable for a single instance, but use separate i variables for each instance? I know I could do something like make a for loop to the first spot in minions[] equal to NULL, or make i a member of Player directly, but I want to know if there is a better way before I do either of those.
Change Object* minions[16]; to a std::vector<Object*> minions;. That way you can just use minions.size() to know how many there are, or minions.push_back(obj); to add one without worrying about array index stuff.
Why don't you simply put i in each Player? I'd rename it something like summonned_minion_count, but that's the actual intent of what you want to do.
Making a local variable static is effectively making it global. You should simply make i a data member of class Player. And probably give it a more descriptive name.
You need to make your i a member variable of Player.
Or even better you could do something like this:
#include <vector>
class Player {
private:
static int const MAX_MINION_COUNT = 16;
std::vector<Object *> minions;
public:
void Summon(Object* obj) {
if (minions.size() < MAX_MINION_COUNT) {
minions.push_back(obj);
}
}
};