- I could just use the Pimpl idiom. However, I see problems with use of vanilla Pimpl as it is standardly defined because I want users of my library to be able to inherit from myFramework::Sprite et al to make their-game specific classes but C++ does not allow inheritance from objects only inheritance from classes. If a myFramework::Sprite is exposed to the user via a creation function that creates a private implementation of a public myFramework::ISprite interface (or whatever) there would be no direct way for the user to inherit from/ implement ISprite while still getting the default myFramework::Sprite behavior. They would have to implement UserSprite that inherits from ISprite but also has a member variable UserSprite::impl that is created via the Sprite creation function my library exposes and then would have to forward calls to UserSprite to UserSprite::impl as appropriare. This just seems to push too much complexity on to the user for my tastes.
- Just forward declare sfml::sprite in myFramework_Sprite.h, have each myFramework::Sprite have a std::unique_ptr<sfml::Sprite> in the header, and include and use it in myFramework_Sprite.cpp. Sfml leaks out in this case as a name in a header. Also not totally sure this would even work ... can you forward declare a namespace marked-up name? (anybody?)
- Same as 2. but just make myFramework::Sprite::impl be a void* and then cast to sfml::Sprite* in the cpp file. This is untidy, un-C++ like e.g. would not be able to use an std::unique_ptr<T> (right?), would have to do a cast plus delete in the destructor.
- Have myFramework::Sprite implement an abstract interface, say, ISprite but also have an "impl" member variable of type unique_ptr<ISprite> and then in the CPP file implement a private class wrapper around sfml::Sprite and forward calls to it in the implementation of myFramework::Sprite. Essentially this is doing work similar to 1. but hiding it from the user. This is what I am currently doing it my codebase, it works but is verbose ... and after a while it just struck me that when it comes down to it this is essentially the same thing as 3., the void* solution, but with some interfaces throw in to disguise that fact and make me feel better about myself
- Make myFramework::Sprite have a private impl member variable of type boost::any, or my only implementation of a boost::any analog.
The other option is throw out one of the premises that led to the line of thought in 1. to 5. above.
6. Use vanilla Pimpl but don't allow, expect, or require users of the framework to inherit from framework classes. Require users to do all callbacks, extensions, and customization of framework objects via composition. I think this would work but it's hard to get my head around. Say you have a UserSprite that has-a framework sprite and you register the framework sprite to receive generic gameloop updates and register it to recieve mouse input updates. If the form of the mouse input callbacks and the generic gameloop updates are std::function<void(myFramwork::Sprite&, ...)> or whatever in that callback there would be no trivial or beginner-friendly way for the callback to retrieve the UserSprite given the myFramwork::Sprite at call time. One could do it by capturing the std::shared_ptr<UserSprite> in lambdas installed in the mouse callback hooks and the generic gameloop hooks, which I think would work, just seems ... i don't know ... confusing?
Thoughts appreciated...