How to call an abstract class method if there is only a pointer to a class, of which I only know that one of its parents is this abstract class?

class A { virtual void Init()=0; }; class B { public: int i; B() : i(0) {}; }; class C : public A, B { public: int i; C() : A(), B() {}; void Init() {}; }; class D : public A { public: int i; D() : A() {}; void Init() {}; }; // представим что тут нельзя написать A вместо void void func(void* ptr); int main() { C obj1; D obj2; func((void*)&obj1); func((void*)&obj2); return 0; } void func(void* ptr) { // так конечно работает, // но как то это не красиво, хотя бы по отношению к D ((C*)ptr)->Init(); } 

upd: Thank you all for participating, the answer ((A*)ptr)->Init(); of course it is obvious, inattention was let down as always, my problem lay in the fact that multiple inheritance does not really work with builder VCL, that is, if C and D are VCL classes, then ((A*)ptr)->Init(); will not work, harsh reality (((

  • And why only multiple inheritance added to C ++? Brrr - dred
  • By the way, multiple inheritance has nothing to do with it - skegg
  • The correct question is, of course, why you cannot choose A * as the type for the func parameter. - gkuznets
  • This, of course, would be the most correct decision - skegg

2 answers 2

In derived classes, the inherited virtual method must also be declared virtual.

 class C : public A, B { public: int i; C() : A(), B() {}; virtual void Init() {}; // то же в классе D }; 

Then you can call this virtual function from the derived class through a pointer to the base class

 void func(void* ptr) { ((A*)ptr)->Init(); //будет вызываться функция либо C::Init, либо D::Init, смотря что передано } 

Or better so

 static_cast<A*> (ptr)->Init(); 

And another note: in class A make the Init() method public

  • 3
    In derived classes, it is not necessary to declare an inherited Wirth. The method is virtual, but you can do it to improve readability. - gkuznets
  • Yes indeed. Did not know. Thanks for the information. - skegg
  • > Or better so> static_cast <A *> (ptr) -> Init (); @mikillskegg, and what's better? Increasing the amount of code? ;) - lirik90
  • one
    Not by increasing the amount of code, but by the fact that ugly structures draw attention to potentially ugly solutions. - gkuznets

Cust in A* must be done when calling a function.

 int main() { C obj1; D obj2; func(static_cast<A*>(&obj1)); func(static_cast<A*>(&obj2)); } void func(void* ptr) { static_cast<A*>(ptr)->Init(); } 

If this is not done, and the order of the bases will be changed ( class C : B, A ), then inside the func pointer will point to B (first base) and not to A