Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factorizing implementations of pure, virtual functions for a subset of classes

Suppose I have this class hierarchy:

class A {
public:
    virtual void foo(Base *b) = 0;
};

class B {
public:
    virtual void bar() = 0;
};


class C : public A, public B {
public:
    virtual void viz() = 0;
};

class E : public C {
public:
    /** Some non-pure virtual functions, does not implement foo */
};

class F : public E {
    /** does not implement foo */
}

class G : public E {
    /** does not implement foo */
}

Now, I would like to define derived, "templatized" versions of F and G, which declares a method foo(T *s) and where the implementation of foo(Base *s) simply calls foo(T *s) by applying a static_cast.

Moreover, I don't wan to expose the template arguments to A, because users of these interfaces (A, B, C, E) should not be exposed to the template parameters (I'm writing a plugin architecture and user-types that derives a given interface are passed back and forth from plugins to base system).

What I thought was to define this class:

template <typename T>
class GA : public A{
...
}

and to define the "templatized" derivations of F and G like this:

template <typename T>
class GF : public F, public GA {
...
}

the problem is that GF sees two different declarations of foo() (one given by A, the other by GA), so the compiler throws me an error when I try to instantiate GF because foo(Base) is not defined.

How can I solve this?

like image 959
akappa Avatar asked Nov 22 '25 05:11

akappa


2 Answers

Why do you need multiple inheritance? Why not just class C : public Impl { ... }?

like image 54
Oliver Charlesworth Avatar answered Nov 24 '25 21:11

Oliver Charlesworth


I think the problem is that Impl inherits class A and class C inherits both Impl and A. This means there will be two instances of class A where first A's foo is implemented by Impl and a seconds one is still pure virtual. Virtual inheritance can solve this problem, for example:

class A {
public:
    virtual void foo () = 0;
};

class Impl : virtual public A {
public:
    virtual void foo () {}
};

class C
    : virtual public A
    , public Impl
{
};

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!