Giewev
Giewev

Reputation: 174

Not Understanding Polymorphic Functions

I am trying to create an array of objects whose class' all inherit from a Base class. Since I am just learning C++ after using Python, this was my first encounter with object slicing. From what I have read I should use pointers to the objects instead of instances of the objects themselves, but I can't seem to make it work.

For example, why does this program output: 1 1 instead of: 1 2

#include <iostream>

class A{
public:
    int getNumber(){
        return(1);
    }
};

class B : public A{
public:
    int getNumber(){
        return(2);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    A* list[2];
    list[0] = new A();
    list[1] = new B();

    std::cout << list[0]->getNumber() << std::endl;
    std::cout << list[1]->getNumber() << std::endl;

    int x;
    std::cin >> x;
    return 0;
}

Upvotes: 0

Views: 69

Answers (3)

Anthony
Anthony

Reputation: 12407

The program is outputting 1 1 because the getNumber function is not marked as virtual. Without the virtual keyword, the A* which points to a B doesn't know to look the function up in a v-table. So it just calls the getNumber function of A.

Declare the function as

virtual int getNumber( );

and you should get the expected behaviour.

Read more about virtual functions and see this question.

Upvotes: 0

Zac Howland
Zac Howland

Reputation: 15870

You are not experiencing object slicing here. This is an example of function hiding.

Basically, since A and B both have a function getNumber, but it is not a virtual function, there is no virtual function table to tell the compiler which function should be called. Instead, it will call the appropriate function based on the type (in this case, A*).

Declare getNumber as virtual in A, and this fixes your problem: virtual int getNumber() { ... }

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385395

You're close, and you seem to understand object slicing just fine. However, object slicing is not taking place here — it's the function calls themselves that are giving you grief.

You need to mark your member functions as virtual in order to take advantage of polymorphism.

(More accurately, in order to take advantage of virtual dispatch.)


class A{
public:
    virtual int getNumber(){  // <--- `virtual`!
        return(1);
    }
};

Upvotes: 3

Related Questions