0

let's say I have a class animal and a class dog that inherits animal. Let's say I want to call a method called 'eat()' that is specific to dog but there is some shared eat code between all animals, so I know I can make 'eat()' virtual but then it won't use the base class code, should I just call my base class 'eatAll()', for example, and then every eat method from a specific animal will have to call that? Just looking for the best design I guess. This is in c++

Chad
  • 18,706
  • 4
  • 46
  • 63
Pittfall
  • 2,751
  • 6
  • 32
  • 61
  • Possible duplicate : http://stackoverflow.com/questions/672373/can-i-call-a-base-classs-virtual-function-if-im-overriding-it – KCH Oct 09 '12 at 19:34

3 Answers3

5

This is classic template method pattern. Basically:

class Animal
{
    void Eat() 
    {
       //stuff specific to all animals

       SpecificEat();
    }
    virtual void SpecificEat() = 0;
};

class Dog : Animal
{
    virtual void SpecificEat()
    {
        //stuff specific to dog
    }
};

Using this approach, you don't have to explicitly call the base class method in derived classes' overrides. It's called automatically by the non-virtual Eat() and the specific functionality is implemented by virtual SpecificEat().

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • what if eat is not void? what if it's a bool for example, how do you work that in? – Pittfall Oct 10 '12 at 19:22
  • @Pittfall the `=0` is the only thing that's valid there, and indicates a pure virtual function. `=true` doesn't make sense. If that confuses you, read up on pure virtual functions and remove the `=0`. – Luchian Grigore Oct 10 '12 at 19:52
  • got it read about pure virtual functions and it makes sense, thanks! – Pittfall Oct 10 '12 at 19:55
4

I would suggest that your base class interface have hooks to call into specific functionality of derived types. This is called the template method pattern. Here's an example:

class Animal
{
public:
   void eat()
   {
      std::cout << "Mmmm... It's ";
      do_eat();
   }

private:
   virtual void do_eat() = 0;
};

class Dog
   : public Animal
{
   virtual void do_eat()
   {
      std::cout << "Dog Food!\n";
   }
};

class Human
   : public Animal
{
   virtual void do_eat()
   {
      std::cout << "Pizza!\n";
   }
};
Chad
  • 18,706
  • 4
  • 46
  • 63
2

Just call the base class' method.

class Dog : public Animal
{
public :
  void Eat()
  {
    // .. MAGIC
    Animal::Eat();
  }
};

Note that if your Animal class's Eat method is pure virtual (which I doubt), this will not link.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • I have already mentioned in my question that I can call the base method from dog and the question was more directed for someone who can back up a good design. "Magic" was not exactly what I was looking for – Pittfall Oct 09 '12 at 19:52
  • @Pittfall: "MAGIC" was just a placeholder for whatever you do in the derived class. – John Dibling Oct 09 '12 at 20:17