0

Let's say we have these classes:

class A {
 virtual void foo() {} //implemented
 virtual void bar() = 0;
};
class B: public A {
 virtual void foo() override {} //implemented
 virtual void bar() override {} //implemented
};
class C: public A {
 virtual void foo() override {} //implemented
 virtual void bar() override {} //implemented
};

Then let's say we do this:

shared_ptr<A> spa;

if (someCondition) {
 spa = make_shared<B>();
} else {
 spa = make_shared<C>();
}

spa->foo();
spa->bar();

What happens in the background? Obviously, pure virtual function bar() MUST be implemented in the derived classes - so is there an implicit cast that happens for the shared ptr to use the derived class implementation? In the case of bar, we are still overriding despite implementation in the base class, so will it also do a an implicit cast of some sort to use the derived class implementation?

Essentially, it's not a question of what will happen, but moreso a question of how what is happening is happening.

Marek R
  • 32,568
  • 6
  • 55
  • 140
Skorpius
  • 2,135
  • 2
  • 26
  • 31
  • 2
    related/dupe: https://stackoverflow.com/questions/3804079/how-does-virtual-method-invocation-work-in-c and https://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained – NathanOliver Mar 13 '19 at 16:09
  • I don't see these explain casting though? – Skorpius Mar 13 '19 at 17:45
  • 1
    No casting happens in the function call. Since all derived objects are also a base object they populate the vtable in the base part with the function address to the derived object function. – NathanOliver Mar 13 '19 at 17:50
  • And this happens implicitly at every pointer reassign? – Skorpius Mar 13 '19 at 19:00
  • 1
    Yes-ish. When you have `class B: public A` you basically get a blob of memory that represents `B`,but the very first part of that blob is the `A` part of `B`. So when you do `A* foo = new B;` foo will point to the `A` part of `B`, but all of the `B` part is still there. It is the `A` part that, when `B` is created, has it's vtable populated to point to `B`'s functions, instead of `A`'s. – NathanOliver Mar 13 '19 at 19:04
  • I see. One last thing. if class B has function that it has on its own, would we have to downcast the pointer to B to call those functions? For example, if class B implements baz() but its not virtual in A, can spa call baz()? – Skorpius Mar 13 '19 at 19:08
  • 1
    Yes, you would hve to cast to `B` since `A` has no idea that function exists. In those cases you would need to use a `dynamic_cast` to make sure you are casting it correctly. Normally though having to call dynamic_cast is considered a design flaw as it should be avoid for the most part. – NathanOliver Mar 13 '19 at 19:10

0 Answers0