Incomplete types question

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jul 7 23:28:49 PDT 2014


On 07/07/2014 09:44 PM, NoUseForAName wrote:
> In C my favorite way of achieving encapsulation is to use incomplete
> types. The module header contains the definition of an incomplete type
> and the prototypes for the public functions which operate on it. I have
> read D has incomplete types too however D does not have headers and as a
> C guy I do not know how to implement this scheme without a .h/.c
> separation.
>
> As I said, in C I put the incomplete declaration in the header while
> keeping the complete declaration private to the module. How do I do this
> in D? I mean type is complete within the module itself (and thus can be
> instantiated there) but incomplete for clients (i.e. other modules) i.e.
> instantiating or modifying data of that type directly is impossible.
>
> P.S.: It seems D lingo for incomplete types is "opaque types".

1) Put the opaque type and its functions into a .di file:

// deneme.di
module deneme;

struct S;

S * makeS(int i);

void useS(S * s);


2) Put the implementation in its .d file:

// deneme.d
module deneme;

import std.stdio;

struct S
{
     int i;

     void foo()
     {
         writefln("Executing foo() for %s", this);
     }
}

S * makeS(int i)
{
     return new S(i);
}

void useS(S * s)
{
     s.foo();
}


3) Compile the implementation as a library (just a .o in this case):

$ dmd deneme.d -c

(That will create the file deneme.o)


4) Write a client program that uses the interface. (Make sure that only 
deneme.di is visible to the client (not deneme.d).)

// main.c
import deneme;

void main()
{
     S * s = makeS(42);
     useS(s);
}


5) Compile (and link) the client program and the library to make the 
program:

$ dmd main.d deneme.o

(That will create the executable 'main'.)


6) Run the program:

$ ./main
Executing foo() for S(42)

Ali



More information about the Digitalmars-d-learn mailing list