impatient salmon
impatient salmon

Reputation: 23

method overriding doesnt work as expected

sorry if the title isnt very good, i couldnt think of anything else

ive got this program:

class Animal
{
    private:
        int legs;
        string sound;
    protected:
        Animal(int l, string s) : legs(l), sound(s) {}
    public:
        Animal() {}
        string getClass()
        {
            return "Animal";
        }
        void printInfo()
        {
            cout <<"This is a(n) "<<getClass()<<". It has "<<getLegs()<<" legs and makes the sound: "<<getSound()<<"\n";
        }
        int getLegs()
        {
            return legs;
        }
        string getSound()
        {
            return sound;
        }
};

class Dog: public Animal
{
    public:
        Dog() : Animal(4,"bark")
        {
        }
        string getClass()
        {
            return "dog";
        }
};

int main()
{
    Animal a;
    Dog d;
    a.printInfo();
    d.printInfo();

    a=d;
    a.printInfo();
    return 0;
}

compiling and running results in this:

This is a(n) Animal. It has 2002819627 legs and makes the sound:

This is a(n) Animal. It has 4 legs and makes the sound: bark

This is a(n) Animal. It has 4 legs and makes the sound: bark

why is it that i get "animal" as the class and not dog when i call printInfo() on d? (but still get the legs and sound correct somehow) i mean, why Dog's getClass wont work when used on printInfo(); am i doing something wrong?

Upvotes: 0

Views: 89

Answers (2)

fas
fas

Reputation: 1413

There are two points:

  1. Use virtual methods, so getClass for Animal() instance would return "Animal" and getClass() for Dog instance would return "dog".
  2. You have used default constructor for a, so legs contains some garbage value, you need to initialize it or remove default constructor.
class Animal
{
    private:
        int legs = DEFAULT_NUMBER_OF_LEGS;
//                 ^^^^^^^^^^^^^^^^^^^^^^
        string sound = "DEFAULT_SOUND";
//                     ^^^^^^^^^^^^^^^
    protected:
        Animal(int l, string s) : legs(l), sound(s) {}
    public:
        Animal() {}
        virtual string getClass()
//      ^^^^^^^
        {
            return "Animal";
        }
        void printInfo()
        {
            cout <<"This is a(n) "<<getClass()<<". It has "<<getLegs()<<" legs and makes the sound: "<<getSound()<<"\n";
        }
        int getLegs()
        {
            return legs;
        }
        string getSound()
        {
            return sound;
        }
};

class Dog: public Animal
{
    public:
        Dog() : Animal(4,"bark")
        {
        }
        string getClass() override
//                        ^^^^^^^^
        {
            return "dog";
        }
};

int main()
{
    Animal a;
    Dog d;
    a.printInfo();
    d.printInfo();

    a=d;
    a.printInfo();
    return 0;
}

Upvotes: 1

yaodav
yaodav

Reputation: 1276

the reason that you're getting the current num of legs but not the animel name it because how constructor works, when you create Dog class you calling the base class constructor with the "right" num of legs and

Dog() : Animal(4,"bark")

but when you calling printInfo Dog is looking for this function but cant find it so it going to its base class and at the base class the class is "Animel". you need to change the base class getInfo ginather to

virtual string getClass()
{
    return "Animal";
}

and this will resolve you problome

Upvotes: 1

Related Questions