I know this might look like a trivial question, but I haven't found really an elegant C++ solution to the following problem.
I want to represent a complex (tree-like) hierarchy of a "world" of objects. Let's say Animals
. Every animal has some basic const properties.
Like for example a name
. Then it also has some methods, but they are not significant for this problem.
class Animal {
public:
const char *GetName() const;
protected:
const char *name;
};
class Insect : public Animal {
...
};
class Butterfly : public Insect {
...
};
In this hierarchy I would like to initialize the name
in every derived (grand)child. What is an elegant solution to this?
It is also important to say that in this "world" there be only instances of the tree leaves. That is, there will be no objects "Animal" or "Insect". But there will be objects "Butterfly", "Bee" or "Mosquito".
I know the "standard" way to do this is to put name
into constructor:
Animal::Animal(const char *name) : name(name) {}
Insect::Insect(const char *name) : Animal(name) {}
Butterfly::Butterfly() : Insect("Butterfly") {}
But if there are more of these properties, the derived classes need also some initialization and the hierarchy has more levels it can become quite a mess:
Animal::Animal(const char *name) : name(name) {}
Vertebrate::Vertebrate(const char *name) : Animal(name) {}
Mammals::Mammals(const char *name) : Vertebrate(name) {}
Ungulate::Ungulate(const char *name) : Mammals(name) {}
Horse::Horse() : Ungulate("Horse") {}
Another option I can see is to drop the const
and assign directly in the grandchild's constructor:
class Animal {
public:
const char *GetName() const;
protected:
std::string name;
};
Horse::Horse() {this->name = "Horse";}
But that is also not optimal, because the const is lost and it is more prone to errors (the initialization can be forgotten).
Is there some better way to do this?