Consider this
1 2 3 4 5 6 7
|
Monster* create_goblin(){
Goblin g;
return &g;
} //here `g' dies
Monster *m = create_goblin();
m->atk(/**/); //`g' no longer exists, `m' is invalid and it's an error to dereference it
|
here the code is returning the memory address of a variable local to the function
the thing is, once the function ends that variable doesn't exist ¿so what would happen if you try to access it?
because c++ makes no checks for valid pointers the behaviour is actually undefined. The program may crash if you are lucky, or may execute as normal, or the variable now has garbage..., whatever.
that scenario is equivalent to your
Monster *pMonster1 = &Goblin();
there is no Goblin object because it died just after that line, so you can't actually do pMonster->atk() and you end up seeing "This crap still isn't working."
¿what does work?
1 2
|
Goblin g;
Monster *ptr = &g; //note, same scope
|
here dereferencing `ptr' is fine, because `g' still exists and will continue to exists along `ptr'
an alternative is to use dynamic allocation, the object will exists till it's
delete
d
1 2 3 4 5 6 7
|
Monster *m;
//...
m = new Goblin();
//...
m->atk();
//...
delete m;
|
(use of smart pointers is recommended)
now, about the weapons
first a simplification
1 2 3 4
|
class Weapon{
std::string name;
int damage;
};
|
a weapon has two members: name and damage.
you went and do
1 2 3 4 5 6 7 8 9 10
|
class Dagger: public Weapon{
Dagger(){
this->name = "Dagger";
this->damage = 5;
}
};
Weapon w = Dagger();
w.name; //Dagger
w.damage; //5
|
so far so good
then later you create a magical weapon, it has mana that it must recharge
1 2 3 4 5 6
|
class Magic_blade: public Weapon{
int mana;
};
Weapon w = Magic_blade();
w.mana; //¿?
|
`Weapon' only knows about its members, that is, name and damage
it does not know about `mana' so that variable is lost, that's object slicing.