PIMPL Idiom in D

Walter Bright newshound2 at digitalmars.com
Mon May 21 21:23:01 UTC 2018


In C, the way to do PIMPL is to write just a struct declaration:

   === s.h ===
   struct S;

   === s.c ===
   #include "s.h"
   struct S { ... };

   === t.c ===
   #include "s.h"
   struct T {
      S* pimpl;
   };

And the users of T cannot access anything in S. The straightforward equivalent 
in D is:

   === s.di ===
   struct S;

   === s.d ===
   struct S { ... }

   === t.d ===
   import s;
   struct T {
      S* pimpl;
   };


But if you don't want to use .di files, such as when compiling all the files 
together with one command, then things get a bit awkward. D doesn't like:

    === s.d ===
    public struct S;
    private struct S { ... }

Making a public alias to a private struct doesn't work, as the struct's members 
are still accessible. I finally found a way:

   === s.d ===
   public struct Spimpl {
       private S* pimpl;
       private alias pimpl this;
   }
   private struct S { ... }

   === t.d ===
   import s;
   struct T {
     Spimpl* s;
   }

and the contents of S are inaccessible to T, while type safety is maintained. 
There are no extra indirections - the alias this takes care of that. s.d can use 
s to directly access S's contents, but t.d cannot.

https://github.com/dlang/dmd/blob/master/src/dmd/func.d#L229
https://github.com/dlang/dmd/blob/master/src/dmd/dinterpret.d#L151

C: http://wiki.c2.com/?PimplIdiom
C++: http://en.cppreference.com/w/cpp/language/pimpl


More information about the Digitalmars-d mailing list