Wes McKinney <wesmck...@gmail.com> writes:

> The abstract/all-virtual base has some benefits:
>
> * No need to implement "forwarding" methods to the private implementation
> * Do not have to declare "friend" classes in the header for some cases
> where other classes need to access the methods of a private
> implementation
> * Implementation symbols do not need to be exported in DLLs with an
> *_EXPORT macro
>
> There are some drawbacks, or cases where this method cannot be applied, 
> though:
>
> * An implementation of some other abstract interface which needs to
> appear in a public header may not be able to use this approach.
> * My understanding is that the PIMPL pattern will perform better for
> non-virtual functions that are called a lot. It'd be helpful to know
> the magnitude of the performance difference
> * Complex inheritance patterns may require use of virtual inheritance,
> which can create a burden for downstream users (e.g. they may have to
> use dynamic_cast to convert between types in the class hierarchy)

I would add these two points, which may or may not be a significant
concern to you:

* When you add new methods to the abstract virtual model, you change the
  ABI [1] and therefore need to recompile client code.  This has many
  consequences for distribution.

* PIMPL gives a well-defined place for input validation and setting
  debugger breakpoints even when you don't know which implementation
  will be used.


[1] The ABI changes because code to index into the vtable is inlined at
the call site.  Adding to your example

  void foo(VirtualType &obj) {
    obj.Method1();
    // any other line to suppress tail call
  }

produces assembly like

  mov    rax,QWORD PTR [rdi]     ; load vtable for obj
  call   QWORD PTR [rax+0x10]    ; 0x10 is offset into vtable

A different method will use a different offset.  If you add a method,
offsets of existing methods may change.  With PIMPL, the equivalent
indexing code resides in your library instead of client code, and yields
a static (or PLT) call resolved by the linker:

  call    _ZN9PIMPLType7Method1Ev@PLT

Reply via email to