0

Really sorry about the title, if there is any appropriate one please do change it to that.

I have written below sample code to understand virtual functions.

class A {
    public:
    virtual int f() {cout << "1";};
};
class B : public A {
    public:
    int f() {cout << "2";}
};
int main()
{
    A a = *new B();
    A* c = &a;
    c->f();
    A* pa = new B();
    pa->f();
    B* b;
}

The above code outputs 12, I expected that it would print 22.

I thought when a virtual function is invoked from a pointer, it gets dynamically binded. So, I don't understand why the above output is different.

pasha
  • 2,035
  • 20
  • 34
  • @Rakete1111, thanks for responding, but I can't understand how this question is related to question about "object slicing". Could you please let me know. – pasha Aug 30 '18 at 18:52
  • Well, what you are experiencing is called "object slicing". Effectively, in the initialization of `a` you are assigning it a `B`, so only the `A` parts of the `B` object will get copied over. This means that things like member variables and vtable info (important for your Q) gets lost! Which is exactly why you get a 1 for the first call. – Rakete1111 Aug 30 '18 at 18:54
  • makes sense, because after calling second f(), i added, 'code' a = *pa; pa = &a; B* b = dynamic_cast(pa); b->f(); and it caused segmentation fault. – pasha Aug 30 '18 at 19:00
  • Exactly, and that works because the object pointed to by `pa` does still have this information! :) – Rakete1111 Aug 30 '18 at 19:00
  • couldn't mention in the above comment what I actually did but it does not matter, I understood why the code's behaving that way, thanks @Rakete1111 – pasha Aug 30 '18 at 19:07
  • @Rakete1111, I got another answer from a friend, he said that the statement A a = *new B(); actually creates object a of type A, so it'll have the vpointer pointing to the table of A. Even though there is object slicing it is not the actual reason for c->f(); to be displaying 1. It seems logical but I guess it's just speculation. – pasha Aug 30 '18 at 19:17
  • I don't understand. Your first sentence is correct. But I don't see how that means that the second sentence is right. c->f() displays 1 exactly because the vtable information of the B object got lost (because you only have an A object, there is no B.) – Rakete1111 Aug 30 '18 at 19:20
  • OK, so we got to this conclusion, first 'a' has it's vpointer pointing to A's table but when object of B is copied to this object, because of slicing it's vpointer didn't get updated with the B object's vpointer. So, it stayed pointing to A's table. Is this correct? – pasha Aug 30 '18 at 19:37
  • Exactly :) Another way of looking at it is that the vtable has to point to things that are part of the object. `a` is not a B, and so there cannot be parts of B in `a` for the vtable to point to. (But I don't want to confuse you! :)) – Rakete1111 Aug 30 '18 at 19:40

0 Answers0