jeudi 24 septembre 2015

Birds, bees and abstract classes

Newbie me is currently stuck at this seemingly simple problem. Let's say I want to write some code about a bunch of animals procreating happily everafter. Obviously, they'd all need a mate() method, so I could define an abstract class like this:

class FemaleAnimal {
public:
    virtual FemaleAnimal mate(const MaleAnimal& a) const = 0;
    virtual MaleAnimal mate(const MaleAnimal& a) const = 0;
}

And derive all the different species:

class FemaleBird : public FemaleAnimal {
public:
    FemaleBird mate (const MaleBird& b) const;
    MaleBird mate (const MaleBird& b) const;
}

class FemaleBee: public FemaleAnimal {
public:
    FemaleBee mate (const MaleBee& b) const;
    MaleBee mate (const MaleBee& b) const;
}

with males implemented likewise. In main(), I want two vectors

males = vector<MaleAnimal>
females = vector<FemaleAnimal>

each of which might contain both birds and bees, and is filled at run time. The species at each index match, so if males[i] is a bee, then females[i] is also a bee, so I can do

vector<FemaleAnimal> femaleOffspring;
vector<MaleAnimal> maleOffspring;
for (int i=0; i<males.size(); ++i){
    femaleOffspring.push_back( females[i].mate(males[i]) );
    maleOffspring.push_back( females[i].mate(males[i]) );
}    

Now, obviously I want the mate() method in the derived classes to implement the one in the base class, but then I'd have to define mate() for animals in general, such as

FemaleBee::mate(const MaleAnimal& a) const;

But bees don't mate with birds. How would I achieve that kind of specialization? Is there some special design pattern for this? I've tried to look into things like covariance, but that was more confusing than helping.

Bonus question: How do I capture the case when males[i] and females[i] are of different species at runtime?

Aucun commentaire:

Enregistrer un commentaire