Reputation: 151
I am modelling an population using an agent-based framework. It's generally not important to distinguish between males and females, other than when animals reproduce, in which it is important to have female agents of breeding age. The breeders then must have animals as a data member. I am trying to get the cleanest implementation of this framework, but I am unsure whether my current approach is the best.
I currently have a base class called Animal
, and a derived class called Breeder
. Breeder
has a unique pointer data member denoting their offspring, which is of animal type:
#include <iostream>
#include <memory>
class Animal
{
private:
int id_;
protected:
int sex_; // 0 = female, 1 = male
public:
Animal() {};
Animal(int id): id_(id) { };
int get_id() const { return id_; };
};
class Breeder : public Animal {
public:
Breeder(int id) : Animal(get_id())
{
sex_ = 0;
id_b = id;
};
private:
int id_b;
std::unique_ptr<Animal> offspring;
public:
void give_birth() {
std::cout << "breeder " << id_b << " is giving birth" << std::endl;
offspring = std::make_unique<Animal> (id_b+1);
};
int get_id_b() { return id_b; };
int get_offspring_id() { return offspring->get_id(); };
};
My problem is that it feels awkward for me to have the derived class with a member variable that is of the base class. Is it awkward?
Also, breeders can access the individual offpsring's public member functions/variables, but presumably the offspring should be able to 'know' their mother, so the base class could have a pointer member to the derived class.
Is there a better way of dealing with this? Maybe two different classes using composition? For instance, should the breeder class have the functionality to give birth?
Upvotes: 1
Views: 140
Reputation: 385144
This is exactly how a linked list of objects should look.
Once you've changed your one offspring into a collection of multiple offspringen, it'll be exactly how a tree of objects should look.
Nothing wrong with that at all. Carry on. 😊
Minor style suggestion: make sex_
an enum class
with Male
and Female
members, not an int
with mapping given only in comments. You'll find it easier to read when your eyes are away from the declaration, and easier to avoid mistakes too.
Upvotes: 1
Reputation: 27577
My problem is that it feels awkward for me to have the derived class with a member variable that is of the base class. Is it awkward?
Not at all (necessarily). If that fits your domain logic then that could be a very good solution.
Upvotes: 3