2

I have a base class called Packet:

// Header File
class Packet {
public:
    virtual bool isAwesome() const {
        return false;
    }
}

and an inherited class called AwesomePacket:

// Header File
class AwesomePacket : public Packet {
public:
    virtual bool isAwesome() const {
        return true;
    }
}

However, when I instantiate an AwesomePacket and call isAwesome(), the method returns false instead of true. Why is this the case?

4
  • 6
    could you include the code where you instantiate it and call the method? Commented Jan 21, 2010 at 20:51
  • To be more precise: could you include a real and complete example, one that compiles out of the box. And please tell us which compiler your are using, which compiler options are active etc. Commented Jan 21, 2010 at 20:53
  • You don't need to prefix the methods in the descendant (child) class with virtual. Commented Jan 21, 2010 at 20:58
  • 3
    Thomas, you are right, but I find it rather useful to mark methods overwritten in child class with virtual - makes it obvious that this was intentional. Commented Jan 21, 2010 at 21:03

2 Answers 2

8

By any chance is your code calling isAwesome in the Packet constructor:

Packet::Packet()
{
    // this will always call Packet::isAwesome
    if (isAwesome())
    {
    } 
}

Even if this Packet constructor is being used to construct the parent object of an AwesomePacket object, this will not call AwesomePacket::isAwesome. This is because at this point in time the object is not yet an AwesomePacket.

Sign up to request clarification or add additional context in comments.

Comments

4

It all depends on how you call the method. Consider this:

AwesomePacket ap;
bool awesomeness0( ap.isAwesome()); // true, call is direct, not through vtable

AwesomePacket& rap( ap );
bool awesomeness1( rap.isAwesome()); // true, call is direct, not through vtable

Packet p( ap ); // WRONG (but legal): slicing child instance into space of parent
bool awesomeness2( p.isAwesome()); // false, call is direct, not through vtable

const Packet& rp( ap ); // the right way
bool awesomeness3( rp.isAwesome()); // true, call is through vtable

const Packet* pp( &ap ); // also the right way
bool awesomeness4( pp->isAwesome()); // true, call is through vtable

This is to say that polymorphism in C++ only works via reference or a pointer to base.

Edit:

Don't forget to add a virtual destructor in the base class.

Edit:

It also depends on where you call your virtual method, see the answer by R Samuel Klatchko.

4 Comments

If I'm not mistaken, your last example should be pp->isAwesome().
The comment on your second example (for awesomeness1) is incorrect. Since rap is a reference, the call is through the vtable, not direct. It is correct that true is returned though.
A mistake only a Java programmer would make, passing an object by value.
Jon-Eric, you are right, sort of. The compiler already knows the exact object type, so it doesn't need to go through the vtable, and might just generate direct instead of virtual call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.