Statically Typed

because Hindley-Milner rocks

Interview Questions


So I read a post on Hacker News that someone’s favorite C++ question was to explain the usage of the keyword “virtual.”  That’s pretty easy to answer and I’m fairly surprised it’s a good weeder.  Here I thought a deeper question into the inner workings of C++ a la typenames and class template declarations was warranted but no.  Such a sad world we live in.  So without further ado the three uses of the word virtual:

  1. Virtual functions.
  2. Virtual destructors.
  3. Virtual inheritance.
Virtual functions

When a pointer of type “A” points to an object of type “B” where B is-an A, the method of object B will be called instead of the method of object A.  Demonstrated like so:

class Foo{
public:
    virtual void bye(){ cout << "bye" << endl; }
    void hi(){ cout << "hi" << endl; }
};

class Bar: public Foo{
public:
    void bye(){ cout << "good bye" << endl;}
    void hi(){ cout << "hello" << endl;}
};

Here if we had a pointer of type “Foo” pointing to an object of “Bar” the call to hi() would result in the message “hi” and not “hello” while a call to bye() would produce the expected “good bye.”

Virtual destructor

Following the example of above let’s assume that class Bar was defined to hold an int.  When we’d call delete on the A type pointer pointing at an object of B if A’s destructor were not virtual then the destructor of A would be invoked.  Since A doesn’t know about the int of type B at the very least we’d leak an int.  But, and you knew that was coming, that’s not all.  It’s actually undefined behavior we’d encounter in this situation.

Therefore, if a class has a virtual method (indicating the class was designed to be in a hierarchy) give it a virtual destructor to avoid undefined behavior.

Virtual inheritance

This one is fun.  It relates to escaping from the diamond hierarchy problem.  Take this little contrived example:

class A{
public:
    int value;
};

class B : public A{};
class C : public A, public B{};

If I chose to set C’s “value” to 4, which value would I set?  The inherited one from A or the inherited one from B?  It gets even harrier when the path from one inherited class leads to one base class instance while another leads to a different one:

class A{
public:
    int value;
};

class B : public A{
    void setValue(int _val){ value = _val; }
};

class C : public A{
    void setVal(int _val){ value = _val; }
};

class D: public B, public C{};
class E: virtual public B, virtual public C{};

If I were to call D’s “setVal” with 3 and “setValue” with 4 what would the call to “value” yield?  I have no idea.  Each path accesses it’s own “value” member.  You’d have to specify “D::B::value” or “D::C::value” to get at the right one.  On the other hand, if I did the same in that order on class E the answer would be 4.  There’s only one “value” in class E, not two.

Have I missed something (other than differentiating between pure virtual and virtual functions?)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on March 30, 2010 by in C++, Intervew Questions.
%d bloggers like this: