Home > Back-end >  C Override a pure virtual method with reference to an abstract class as a parameter by method that
C Override a pure virtual method with reference to an abstract class as a parameter by method that

Time:04-22

I have the following code:

struct A{ f()=0; };
struct Aa : A{ f(){} };
struct B{
   void foo(A&)=0;
};
struct Bb : B{
   void foo(Aa&);
};

Right now I can't create a Bb class instance since I didn't override foo from class B with demanded parameter. How can I make it work?

CodePudding user response:

lets assume it is possible/compiles and add extra class:

struct A{ void f()=0; };

struct Aa : A{ int x; void f(){} };
struct Ab : A{ double x; void f(){} };

struct B{
   void foo(A&)=0;
};
struct Bb : B{
   void foo(Aa&);
};

Now how this should work?

std::unique_ptr<B> p = std::make_unique<Bb>;
Ab a;
p->foo(a); // ???

how overridden function Bb::foo should handle this scenario? It expected something of type Aa, but got Ab which is not child of Aa. From B::foo perspective this call is perfectly fine since Ab is child of A.

This should give you a hint why compiler didn't do what you have expected.

CodePudding user response:

How can I make it work?

You cannot make it work without changing the premises. void(Aa&) cannot override void(A&). The parameter types must match.


Generally in object oriented programming, an overriding function cannot never have more strict parameter type.

Some object oriented languages support contravariant parameters in derived functions, which allows overriding with a function that accepts a more general parameter. For example, member function accepting `A&` could override a member function accepting `Aa&` (i.e. other way around compared to your attempt). However, C does not support contravariant parameters. The parameter types must match exactly.

Perhaps dynamic polymorphism isn't what you need. Perhaps you need static polymorphism (templates):

template<
    std::derived_from<A> TA
    // or if you don't have concepts:
    // class TA
>
struct B{
   void foo(TA&) {
       // use somehow
   }
};

using Bb = B<Aa>;
  • Related