Public Group

# Cannot initialize constant base member value

This topic is 1332 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Okay, I've literally struggled with this for hours, because I had a base class that had a value

class base
{
public:
const __int32 ID;
};


the ID would be filled with a value that designates what kind of entity it is, and the program wouldn't work unless I also defined a const __int32 ID in my child classes as well. This led to ambiguous use of ID which caused me many hours of frustration. And now I simply can't figure out how to do it; if I remove the second ID from the child class it won't allow me to use the constant in my base class under any circumstance. I've looked online and nobody else seems to have this issue. I tried doing fancy things with overloading constructors and whatever, but the compiler will not let this go. I don't know what rule is keeping me from assigning an ID value into my child class when creating a new object of this type. I wouldn't know what this issue is called. I have the error code and that didn't help me. (For instance, C2614: 'Block' : illegal member initialization: 'ID' is not a base or member)

I'm really tired and out of it and I essentially spent an all nighter on a probably really stupid thing. Does anyone know what problem I'm having so I can move on with my life?

##### Share on other sites

Okay, sorry, again, I'm tired, so I'm skimming details. I do have that.

class Entity
{
static unsigned short Count;

public:
Entity() : ID (eIDError) {}
Entity(EntityIDs id) : ID (id) {}
const __int32 ID;
};

class Block : public Entity
{
public:
Block() : ID (eIDError) {}
Block(EntityIDs id) : ID (id) {}
};

In the Block class it gives me the same aforementioned error:

error C2614: 'Block' : illegal member initialization: 'ID' is not a base or member

Unless I redefine ID in the child class, which again, brings up issues over the ambiguous ID.

##### Share on other sites

You need to call the base-class constructor, not attempt to initialise the base-class variable directly. Something like:

Block() : Entity(eIDError) {}

##### Share on other sites

Oh gosh. Thank you so very much. Everything's working now.

Edited by Akashi

##### Share on other sites

I'm using the EntityIDs enum to differentiate between what kinds of objects are colliding during each Collide() function. So my IDs consist of things like Block, Player, Enemy, etc. It's what I'd figure I'd use. Since I don't intend to have any of the types change it's also a constant that is accessible publicly so I don't have to have a GetType function. Just other->ID. That's still fine, right? Though I guess it is kind of a hassle with stuff like this.

I've seen games that have entities that each have unique IDs. Would I come up with some method for generating one and then initialize them with that unique ID in a similar fashion?

Edited by Akashi

##### Share on other sites
There are many other options for that.

Probably the easiest that also avoids a virtual function is to make the variable private, accept the value in a constructor, and write a non-virtual inline accessor function that returns the value.

##### Share on other sites

I'm using the EntityIDs enum to differentiate between what kinds of objects are colliding during each Collide() function. So my IDs consist of things like Block, Player, Enemy, etc. It's what I'd figure I'd use. Since I don't intend to have any of the types change it's also a constant that is accessible publicly so I don't have to have a GetType function. Just other->ID. That's still fine, right? Though I guess it is kind of a hassle with stuff like this.

Yep, that's still fine.

EntityIDs implies (at least to me) that it's a unique identifier per entity instance. EntityTypeID would perhaps be a better name, since it implies each type of entity (Block, Enemy, etc...) has a unique ID.

I've seen games that have entities that each have unique IDs. Would I come up with some method for generating one and then initialize them with that unique ID in a similar fashion?

Having a unique ID per-entity is useful for other purposes, but isn't what you want here for implementing your collision logic. If you want both (for those other uses), you could do it like:

//__int32 is implementation-specific. int32_t and uint32_t are standardized,
//but you need to #include <cinttypes> for it.
#include <cinttypes>

enum class EntityType { Player, Block, Enemy };

class Entity
{
public:
const uint32_t ID; //Unique per entity.
const EntityType Type; //Unique per type.

public:
Entity(uint32_t id, EntityType entityType) : ID(id), Type(entityType) { }

protected:
static uint32_t generateNextID() { return ++nextEntityID; }

private:
static uint32_t nextEntityID = 0;
};

class Block
{
public:
Block() : Entity(Entity::generateNextID(), EntityType::Block) { }
};

<opinion>

...but personally, I don't think entities should know their own ID. Usually, the ID is only used outside of the entity class to find the right entity, so I just do std::unordered_map<EntityID, Entity>, where the map is allowed to do its job of mapping the IDs to the entities.
And if performance becomes an issue during iteration, due to thousands of entities at once, I'd use a vector of entities with a unordered_map<EntityID, VectorIndex> backing it up.
</opinion>

But the simplest way starting out would be to keep the ID in the entity, and keep the entities in a vector, and search the vector for the correct entity when needed.

Important: Don't forget that when using polymorphism (i.e. treating a Derived as if it's a Base), you must refer to your instances by pointers! You can't do Base myBase = Derived, or it crams the bits of the Derived into a Base variable, parts of it get lost, and bad things result.

1. 1
2. 2
3. 3
4. 4
5. 5
Rutin
15

• 14
• 9
• 9
• 9
• 10
• ### Forum Statistics

• Total Topics
632912
• Total Posts
3009197
• ### Who's Online (See full list)

There are no registered users currently online

×