0

I have the following typical scenario, in which I want to hide implementation details in a child class, and expose it through an interface:

template <typename Derived>
class Interface
{
public:
    void a()
    {
        static_cast<Derived*>(this)->_a();
    }
};

class Implementation : public Interface<Implementation>
{
protected:
    void _a()
    {
        /*
        ...
        */
    }
};

I think I understand why this doesn't work, and I know that declaring the class Interface as friend of Implementation solves it, but when it comes to more complex hierarchies, like multiple interfaces, and various levels of inheritance(as is my real case), things get really messy.

I would like to avoid having to declare friend class Interface<Implementation> in each class that implements an interface.

Is there an alternative nice-and-clean solution for this problem?

Thanks!

  • 1
    Make `_a()` not protected? That or `friend` is the only way to go really. – Barry May 30 '15 at 21:18
  • Of course that's a solution, but then everyone could access _a(), which is what I don't want to do. Without CRTP this case is really easy, so I thought it could also be done with it – Federico Allocati May 30 '15 at 21:23
  • Do not expose objects of Implementation type in your module's interface then everyone can not access those. – Öö Tiib May 30 '15 at 21:26
  • Why can't consider impl as a `private shared_ptr` within interface class? – Steephen May 30 '15 at 21:34
  • @Barry Why is it the only way to go? The ctor of the object of the class instantiating ``Derived`` can pass to ``Interface``'s ctor enough information on how to call it, no? – Ami Tavory May 30 '15 at 21:45
  • 1
    http://www.drdobbs.com/cpp/making-pimpl-easy/205918714?pgno=1 has a good explanation of how to make the pimpl idiom easier across large scale applications, without the need to make `Implementation` `public` or a `friend` – Tas May 30 '15 at 22:12
  • Possible duplicate of [CRTP with Protected Derived Member](http://stackoverflow.com/questions/8523762/crtp-with-protected-derived-member) – Edward Aug 16 '16 at 23:46

1 Answers1

1

How about using virtual functions and polymorphism?

Create an object in your child class and reassign it to an interface class pointer or reference. Then create a pure virtual function in your interface class and define it in your child class.

Wandering Fool
  • 2,170
  • 3
  • 18
  • 48
  • 1
    That's a good idea, but CRTP is often used to avoid the cost of virtual functions. – Ami Tavory May 30 '15 at 21:40
  • @AmiTavory This is the first time I've heard about the CRTP idiom. I don't think I can be of much more help. But that's good to know that CRTPs eliminate the need for v-tables. – Wandering Fool May 30 '15 at 21:43
  • (love the name, BTW) To be precise, CRTP doesn't eliminate the need for v-tables in all cases. – Ami Tavory May 30 '15 at 21:47