0

I'm trying to workout a problem in C++ regarding inheritance and wondering how to go about doing it correctly.

I have 3 classes set up: - Enemy (which has member data: int Damage, int Health and int Level) - Wolf - Bear

The way my inheritance is set up is: Wolf is-a Enemy and Bear is-a Enemy. In other words, both Wolf and Bear inherit from Enemy.

I want to set up my program so that when I create a new Enemy like so:

Enemy anEnemy; 

Then in Enemy::Enemy() constructor it will randomly decide whether that enemy is a Wolf or a Bear.

How would one approach this problem? I know I'd have to generate a random number in the Enemy::Enemy() constructor and based on the result of the random number it would turn the enemy into either a bear or wolf. But I just can't wrap my head around how to "turn it" (the enemy) into a wolf or a bear.

Any help would be really appreciate. Thanks!

2
  • "But I just can't wrap my head around how to "turn it" (the enemy) into a wolf or a bear." You don't "turn" these instances into a wolf or a bear, but have these (wolf/bear) instantiated in 1st place. Check what std::unique_ptr<Enemy> or std::shared_ptr<Enemy> can do for you. Commented Mar 16, 2015 at 23:49
  • Lookup the "Factory" design pattern. Commented Mar 16, 2015 at 23:56

2 Answers 2

2

To decide the type randomly at run time, then for type safety you practically have to use dynamic allocation, e.g.

Enemy* p_enemy = random_enemy(); // Use p_enemy here, e.g. p_enemy->make_noises(), then: delete p_enemy; 

where random_enemy is a function like

auto random_enemy() -> Enemy* { return (my_random_number() > 0.5? new Wolf : new Bear); } 

As you'll discover, however, manual delete is difficult to get right in many/most situations. Therefore it's common to automate that, by using smart pointers such as std::unique_ptr and std::shared_ptr. Then the usage code might look like:

unique_ptr<Enemy> p_enemy = random_enemy(); // Use p_enemy here, e.g. p_enemy->make_noises(), then it auto-deletes. 

And the function like

auto random_enemy() -> unique_ptr<Enemy> { return unique_ptr<Enemy>( my_random_number() > 0.5? new Wolf : new Bear ); } 
Sign up to request clarification or add additional context in comments.

Comments

1

You have 2 problems right now :

First, polymorphism (look it up) is based on references or pointers, not values. Therefore, when you create your Ennemy (who might be a Bear or Wolf "at random") you cannot hold a variable of value type to it, because the type won't always be the same.

Ennemy my_ennemy = (Bear or Wolf); // This is impossible. 

Essentially Bear and Wolf are not the same type, and not even of the same size, so they cannot fit inside an allocated Ennemy-sized amount of memory.

You need something along these lines :

Ennemy *my_ennemy = new Bear(); // OR Bear someExistingBear; Ennemy *my_ennemy = &someExistingBear; // Or even std::unique_ptr<Ennemy> my_ennemy(new Bear()); 

Conversely, you have to decide whether to build a Bear or a Wolf outside of the Ennemy constructor.

You could use a free function like so :

Ennemy *make_ennemy() { // Some random way to choose. Probably with a static seed. if (isbear) return new Bear(); else return new Wolf(); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.