std::map for storing static const Objects

Posted by Sean M. on Game Development See other posts from Game Development or by Sean M.
Published on 2013-10-31T21:42:54Z Indexed on 2013/10/31 22:19 UTC
Read the original article Hit count: 381

Filed under:
|
|
|

I am making a game similar to Minecraft, and I am trying to fine a way to keep a map of Block objects sorted by their id. This is almost identical to the way that Minecraft does it, in that they declare a bunch of static final Block objects and initialize them, and then the constructor of each block puts a reference of that block into whatever the Java equivalent of a std::map is, so there is a central place to get ids and the Blocks with those ids.

The problem is, that I am making my game in C++, and trying to do the exact same thing. In Block.h, I am declaring the Blocks like so:

//Block.h
public:
    static const Block Vacuum;
    static const Block Test;

And in Block.cpp I am initializing them like so:

//Block.cpp
const Block Block::Vacuum = Block("Vacuum", 0, 0);
const Block Block::Test = Block("Test", 1, 0);

The block constructor looks like this:

Block::Block(std::string name, uint16 id, uint8 tex)
{
//Check for repeat ids
if (IdInUse(id))
{
    fprintf(stderr, "Block id %u is already in use!", (uint32)id);
    throw std::runtime_error("You cannot reuse block ids!");
}
_id = id;
//Check for repeat names
if (NameInUse(name))
{
    fprintf(stderr, "Block name %s is already in use!", name);
    throw std::runtime_error("You cannot reuse block names!");
}
_name = name;

_tex = tex;
//fprintf(stdout, "Using texture %u\n", _tex);

_transparent = false;
_solidity = 1.0f;

idMap[id] = this;
nameMap[name] = this;
}

And finally, the maps that I'm using to store references of Blocks in relation to their names and ids are declared as such:

std::map<uint16, Block*> Block::idMap = std::map<uint16, Block*>(); //The map of block ids
std::map<std::string, Block*> Block::nameMap = std::map<std::string, Block*>(); //The map of block names

The problem comes when I try to get the Blocks in the maps using a method called const Block* GetBlock(uint16 id), where the last line is return idMap.at(id);. This line returns a Block with completely random values like _visibility = 0xcccc and such like that, found out through debugging.

So my question is, is there something wrong with the blocks being declared as const obejcts, and then stored at pointers and accessed later on? The reason I cant store them as Block& is because that makes a copy of the Block when it is entered, so the block wouldn't have any of the attributes that could be set afterwards in the constructor of any child class, so I think I need to store them as a pointer.

Any help is greatly appreciated, as I don't fully understand pointers yet. Just ask if you need to see any other parts of the code.

© Game Development or respective owner

Related posts about c++

Related posts about opengl