Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typecasting with virtual functions

In the code below, pC == pA:

class A
{
};

class B : public A
{
public:
    int i;
};

class C : public B
{
public:
    char c;
};

int main()
{
    C* pC = new C;
    A* pA = (A*)pC;

    return 0;
}

But when I add a pure virtual function to B and implement it in C, pA != pC:

class A
{
};

class B : public A
{
public:
    int i;
    virtual void Func() = 0;
};

class C : public B
{
public:
    char c;
    void Func() {}
};

int main()
{
    C* pC = new C;
    A* pA = (A*)pC;

    return 0;
}

Why is pA not equal to pC in this case? Don't they both still point to the same "C" object in memory?

like image 648
user987280 Avatar asked Apr 03 '12 22:04

user987280


1 Answers

You're seeing a different value for your pointer because the new virtual function is causing the injection of a vtable pointer into your object. VC++ is putting the vtable pointer at the beginning of the object (which is typical, but purely an internal detail).

Let's add a new field to A so that it's easier to explain.

class A {
public:
    int a;
};
// other classes unchanged

Now, in memory, your pA and A look something like this:

pA --> | a      |          0x0000004

Once you add B and C into the mix, you end up with this:

pC --> | vtable |          0x0000000
pA --> | a      |          0x0000004
       | i      |          0x0000008
       | c      |          0x000000C

As you can see, pA is pointing to the data after the vtable, because it doesn't know anything about the vtable or how to use it, or even that it's there. pC does know about the vtable, so it points directly to the table, which simplifies its use.

like image 156
Derek Park Avatar answered Oct 09 '22 14:10

Derek Park