Reputation: 791
I have a class(names as example):
class Animal
{
public:
// some virtual methods
};
There are also some sub-classes.
class Dog : public Animal
{
public:
Dog(Map&);
// methods - using m_Map
private:
Map& m_Map;
};
class Elephant : public Animal
{
public:
Elephant(Map&);
// methods - using m_Map
private:
Map& m_Map;
};
As you can see, when creating Dog and Elephant objects, Map reference must be provided, and these classes uses it. There are a lot of more similar sub classes of Animal(Dog, Elephant, Mouse, Cat, and more...) - all uses Map object.
All sub-classes of Animal uses Map object, I was thinking about if it would be good idea to add it to Animal class as protected member, for example:
class Animal
{
public:
Animal(Map&);
// some virtual methods
protected:
Map& m_Map;
};
class Dog : public Animal
{
public:
Dog(Map& map) : Animal(map);
// methods - using Animal::m_Map
};
class Elephant : public Animal
{
public:
Elephant(Map& map) : Animal(map);
// methods - using Animal::m_Map
};
However, Animal class will never use Map object, so it seems for me a bit not natural to store it here - for only sub-classes usage.
On the other hand, all sub-classes of Animal will use Map object - so it would be good to indicate it in Animal class. And also I have feeling that code is duplicated when I define it as member in all sub-classes.
What do you think about it? Should Map object be defined as member in all sub-classes, or only in Animal class?
Upvotes: 1
Views: 91
Reputation: 23
The map object would be defined in animal class only.why because you are inherit animal class properties for all your sub classes.
it is a advantage , you can create object for animal class ,and you can access the map until you did not have any pure virtual methods in animal class
when it comes to memory size of an object,there is no difference where you are holding the map ,whether in a in a base class or derived class.the size of an derived object will be same only
class animal
{
public:
int animal_id;
int animal_age;
};
class dog :public animal
{
public:
int dog_type_id;
};
int main()
{
dog d1;
animal a1;
cout<<"sizeof d1:"<<sizeof(d1)<<endl;
cout<<"sizeof a1:"<<sizeof(a1)<<endl;
return 0;
}
Upvotes: 0
Reputation: 674
If a variable or function is required for all derived types of a base type, then that variable or function should be a part of the base type. This is the very premise of inheritance - de-duplication of code in a logical and systematic manner.
You mentioned that you are struggling with the fact that an Animal object will never actually use a Map. Have you considered a design of your type hierarchy which involves Animal being an abstract class? This means that an Animal would never be instantiated. This makes sense conceptually in the given example - no animal is an animal alone; the category of animal encompasses many other, more specific concepts such as a dog or cat.
I would suggest that this implementation fits your example and resolves your philosophical conundrum.
Upvotes: 0
Reputation: 36431
It depends on the semantic links in between animals and maps.
Since you are in C++, then you can use multiple inheritance.
First, implement a MapWrapper
class:
class MapWrapper {
private:
Map *theMap;
public:
...
};
and then construct your animals like this:
class Dog : public Animal, private MapWrapper {
};
Note that private
inheritance is not generalization/specialization, just a trick to implement some kind of strong composition.
Another possibility is to introduce an intermediate class in between Animal
and Dog
. Animal
is probably a pure abstract class or a contract, so it is probably not fair to modify it for pragmatic purposes. Just introduce an AnimalMap
:
class AnimalMap : public Animal {
// everything for the map
};
class Dog : public AnimalMap {
};
Upvotes: 2