I'm currently developing an application using [SFML][1]. My biggest concern at the moment is making a layer of abstraction over the library, so I can easily change it to something else if needed. What I'm struggling with is designing an abstraction that's intuitive and not [leaky][2].

An example: drawing in SFML is done using drawable objects (implementing `sf::Drawable`) and objects capable of rendering them (`sf::RenderTarget`). 

Say I want to wrap those and create my own `IDrawable`:

    class IDrawable {
    public:
        virtual void draw(IRenderTarget& target) const = 0;
    };

Even though it looks nice, in order for the concrete classes to achieve their goal, they **somehow** still need to exchange information specific to SFML, i.e. `IRenderTarget` has to declare an abstraction breaking method, such as 

    virtual sf::RenderTarget& impl() = 0;


The only solution I can think of is creating concrete classes that require **all** library-specific parts to be passed via constructor, so there's no cross-class communication of library-specific data. This way, `IDrawable` would change to:

    class IDrawable {
    public:
        virtual void draw() = 0;
    }; 


Another solution would be abusing the friending mechanism, but I guess that's not great, either.

In other words -- is there an approach for wrapping a 3rd party library, so that the created abstraction is not leaky (doesn't require public accessor methods that break the encapsulation)? 


  [1]: https://www.sfml-dev.org/
  [2]: https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/