0

In the program hereafter, I have a class animal, that has derived classes cat and dog with the same public functions but different private functions. I would like to let the user decide during runtime which animal is being created. I have made a simple example that shows what I approximately want, but which obviously doesn't work. I don't know how to solve this and would like to have your help.

#include <cstdio>

class canimal
{
  public:
    int sound()
    {
      std::printf("...\n");
      return 0;
    }
};

class cdog : public canimal
{
  public:
    int sound()
    {
      std::printf("Woof!\n");
      return 0;
    }
};

class ccat : public canimal
{
  public:
    int sound()
    {
      std::printf("Mieau!\n");
      return 0;
    }
};

int main()
{
  canimal *animal;
  cdog    *dog;

  // I would like to let the user decide here which animal will be made
  // In this case, I would like the function to say "Woof!", but of course it doesn't...
  animal = new cdog;
  animal->sound();

  // Here it works, but I would like the pointer to be of the generic class
  // such that the type of animal can be chosen at runtime
  dog    = new cdog;
  dog->sound();

  return 0;
}
Chiel
  • 6,006
  • 2
  • 32
  • 57
  • 1
    As the below answers already discussing that you should make `sound()` as `virtual`. Also note that since you are doing dynamic allocation using `new`, you must have a `virtual ~canimal()` destructor as well. – iammilind Mar 12 '13 at 09:25

3 Answers3

3

You need to make the sound() method virtual:

class canimal
{
  public:
    virtual int sound()
    ^^^^^^^

This will make it behave exactly as you need.

For further discussion, see Why do we need Virtual Functions in C++?

In C++ 11 there is a new override keyword that, when used appropriately, makes certain types of errors less likely. See Safely override C++ virtual functions

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

I think you are looking to make sound() virtual. Read up on polymorphism in C++.

class canimal
{
  public:
    virtual int sound()
    {
      std::printf("...\n");
      return 0;
    }
};
Eric Johnson
  • 696
  • 4
  • 23
1

You need to use virtual

i.e.

class canimal
{
  public:
    virtual int sound()
    {
      std::printf("...\n");
      return 0;
    }
};

class cdog : public canimal
{
  public:
    virtual int sound()
    {
      std::printf("Woof!\n");
      return 0;
    }
};

class ccat : public canimal
{
  public:
    virtual int sound()
    {
      std::printf("Mieau!\n");
      return 0;
    }
};
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • Thank you, I guess if I don't want to introduce another level of inheritance, I do not need to make the derived functions virtual? – Chiel Mar 12 '13 at 09:28
  • You could also make `canimal` a pure virtual function so that only derived objects can be created. This is done by `virtual in sound() = 0;` – Ed Heal Mar 12 '13 at 09:48