C ++ `virtual` keyword behavior for objects instead of pointers

I tried to understand virtual functions.

Consider the following code:

#include <iostream> #include <memory> #include <vector> class Animal { public: virtual void eat() { std::cout << "I eat like a generic animal.\n"; } }; class Wolf : public Animal { public: void eat() { std::cout << "I eat like a wolf!\n"; } }; int main() { Animal a; Wolf w; a.eat(); w.eat(); 

}

With the virtual I get output

 I eat like a generic animal. I eat like a wolf! 

as it should be.

But if I delete the virtual keyword, I still get the same result! From my basic understanding of virtual functions, without virtual I had to get a way out

 I eat like a generic animal. I eat like a generic animal. 

Is there anything elementary here I am missing?

I am using g ++ compiler on Linux

+4
source share
3 answers

Polymorphism works by identifying the type of object that the instance actually refers to.

In your case, your actual animals:

 Animal a; //a is an animal. Wolf w; //w is a wolf. 

So you are not using polymorphism at all.

What you need to do is:

 //Create a couple animal pointers. Animal* a; Animal* b; //Create an animal instance and have a point to it. a = new Animal(); //Create a wolf instance and have b point to it. b = new Wolf(); //Calls Animal::eat as a is an animal. a->eat(); //Calls Wolf::eat as a is a wolf. b->eat(); 

Please note that you can use pointers or links to achieve this use of polymorphism.

This is why you should usually pass objects by const-reference when working with class types.

 //Will call Animal::eat or Wolf::eat depending on what animal was created as. void foo(const Animal& animal) { animal.eat(); } //Will always call Animal::eat and never Wolf::eat since this isn't a reference or //a pointer. Will also "slice" a Wolf object. void foo(Animal animal) { animal.eat(); } 

Note that a slice means that it will turn a more derived class (wolf) into a less derived copy of this class (animal) indiscriminately, which can be very erroneous and unexpected.

+4
source

No, this is the correct behavior. Virtual functions are required to introduce polymorphism. To enable polymorphic behavior, you need to use pointers such as this:

  Animal * a = new Animal(); Animal * w = new Wolf(); a->eat(); w->eat(); <...> delete a; delete w; 

Assuming you have it now, the behavior is correct, because both variables obviously have different types.

+5
source

This is another method, even without a virtual one. The virtual keyword allows polymorphic behavior in such cases:

 Animal* wolf = new Wolf; // I eat like a wolf! (as long as eating is virtual) 

Using the virtual keyword, you tell the compiler to select the appropriate implementation to call at runtime based on a derived type.

+1
source

All Articles