I'm creating an API for any C++ library which is distributed inside a dll / shared object. The library consists of polymorhic classes with virtual functions. I'm concerned when I expose these virtual functions around the DLL API, I cut myself from the potential of stretching exactly the same classes with increased virtual functions having to break binary compatibility with programs designed for the prior version from the library.
One option is to make use of the PImpl idiom to cover all of the classes getting virtual functions, but which appear to possess it's restrictions: by doing this programs loose the potential of subclassing the classes from the library and overriding the virtual techniques.
How does one design a API class which may be subclassed within an application, without losing the chance to increase the API with (not abstract) virtual techniques inside a latest version from the dll while remaining backward binary compatible?
Update: the prospective platforms for that library are home windows/msvc and linux/gcc.
Several several weeks ago I authored articles known as "Binary Compatibility of Shared Libraries Implemented in C++ on GNU/Linux Systems" [pdf]. While concepts offer a similar experience on Home windows system, I am sure they are not the identical. But getting browse the article you can aquire a notion on what's happening at C++ binary level which has anything related to compatibility.
Incidentally, GCC application binary interface is made clear inside a standard document draft "Itanium ABI", so you will have a formal ground for any coding standard you select.
Only for a fast example: in GCC you are able to extend a category with increased virtual funcitons, if not one other class gets it. Browse the article for better group of rules.
But anyway, rules are occasionally far too complex to know. So you may want to consider something that certifies compatibility of two given versions: "ABI compliance checker" for Linux.
There's a fascinating article around the KDE understanding base that describes the do's and do nots when striving at binary compatibility when writing a library: Guidelines/Binary Compatibility Difficulties With C++
C++ binary compat is usually difficult, even without inheritance. Take a look at GCC for instance. Within the last ten years, I am unsure the number of breaking ABI changes they have had. Then MSVC includes a different group of conventions, so connecting to that particular with GCC and the other way around can not be done... Should you match it up towards the C world, compiler inter-op appears a little better there.
If you are on Home windows you should think about COM. While you introduce new functionality you can include connects. Then phone callers can
QueryInterface() for that brand new one to reveal that new functionality, and even when you finish up altering things a great deal, you may either leave that old implementation there or write shims for that old connects.
I believe you get me wrong the issue of subclassing.
Here's your Pimpl:
// .h class Derived // .cpp struct Impl: public Base people void Derived::test1() void Derived::test2()
See ? Not a problem with overriding the virtual techniques of
Base, you need to simply make certain to redeclare them
Derived to ensure that individuals drawing from Derived know they might rewrite them as well (only when you want so, which incidentally is a superb method of supplying a
final for individuals who lack it), and you'll still redefine it on your own in
Impl which might even call the
There's not a problem with
However, you lose polymorphism, which might be difficult. The choice is yours to determine whether you would like polymorphism or simply composition.