1

i have a question about virtual functions or methods. I found a really nice post here on stackoverflow link to post explaining why and how virtual functions work. I understand how virtual functions work now, but i still dont understand WHY u need them. If you look at the link and the provided example, he creates an instance like this:

A *a1 = new B;
a1->show();

But why would u ever want to create an instance like this if you want to use functions from B? Why not do it like this:

B b1 = new B;
b1->show();

why should i use the A pointer when i want to use a B reference?

I hope you guys understand what i dont get about this and can explain it to me.

Community
  • 1
  • 1
mirc00
  • 63
  • 3
  • 1
    You need to understand the whole idea behind polymorphism...the following link might help... http://stackoverflow.com/questions/1031273/what-is-polymorphism-what-is-it-for-and-how-is-it-used – Tejendra Apr 27 '16 at 19:11
  • 1
    Take a look at this: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list although any book on basic oop should explain the concept. – eerorika Apr 27 '16 at 19:13
  • 1
    I give a concrete example in [my answer](http://stackoverflow.com/a/27099751/464581) to the question you link to. – Cheers and hth. - Alf Apr 27 '16 at 19:17

3 Answers3

2

Extend the code base to also include a class C that's derived from A.

Now add a function display_A, which is defined as:

void display_A(A* aPtr)
{
   a->show();
}

You can use that function with an instance of B as well as an instance of C.

B* bPtr = new B;
C* cPtr = new C;

display_A(bPtr);
display_A(cPtr);

Here, a B* and a C* are automatically cast to A* before the call to display_A. aPtr->show() in display_A works regardless of whether aPtr points to a B or a C. That's the real motivation for creating virtual functions.

The purpose of using

A *a1 = new B;
a1->show();

is to demonstrate that B::show() gets called even when the pointer is of type A* if what the pointer points to is really a B object.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

This is a good example of Polymorphism.

In short, polymorphism allows two different types (classes) to offer the same interface with different underlying implementations.

Rather than using A and B as an example, consider two classes Motorcycle and Car. Both motorcycles and cars can be driven, right? The way in which you drive those two vehicles is pretty different. Both classes should offer a drive() method, although their implementations are different.

class Vehicle {
    public:
        virtual void drive() = 0;
}

class Car : public Vehicle {
    public:
        void drive() {
            // Driving to work, however a car does that.
        };
}

class Motorcycle : public Vehicle {
    public:
        void drive() {
            // Driving to work, however a motorcycle does that.
        };
}
Vehicle *car = new Car;
Vehicle *motorcycle = new Motorcycle;

// We can both be driven, so we share the same interface.
car->drive();
motorcycle->drive();

This can be particularly useful when passing objects into functions. You have a function which implenments being taken to work. You really don't care how you get to work, as long as you are driven somehow.

void driveToWork(Vehicle *vehicle) {
    vehicle->drive();
}

driveToWork(new Car);

// It's Tuesday, your car broke down!
// As long as we use a Vehicle to get to work, all is well.
driveToWork(new Motorcycle);
  • What language is this? – Slava Apr 27 '16 at 19:39
  • In C++ object passed by value will be sliced. Syntax for call a method for an object is incorrect. If you mean pointers you should use them and you introduce memory leaks. – Slava Apr 27 '16 at 19:43
  • @Slava, I'm answering his question of why this is useful, not providing production ready code. – ricanontherun Apr 27 '16 at 19:45
  • Nobody would expect you to provide production ready code, but introducing bad practice is questionable and `driveToWork(new Car);` is one, it either leads to memory leak or would require to call delete inside function. – Slava Apr 27 '16 at 19:47
1

Bottom line is that when you call a virtual function, it executes the most derived form of that function that it can.

class Message
{
     virtual void buildMessage();
}

class ShutdownMessage : public Message
{
     virtual void buildMessage() { /* Do a thing. */ }
}

class StartupMessage : public Message
{
     virtual void buildMessage() { /* Do a totally different thing. */ }
}

void prepareMessage(Message *M)
{
    M->buildMessage();
}

Now you can call this:

prepareMessage(myMsg);

on any message, and it will call the appropriate buildMessage function.

C. Korb
  • 287
  • 1
  • 10