另一種方法是基於D的系統類的層次上:
所有對象繼承或明或暗地在對象。
這樣的想法是PIMPL實現在OuterClass,生成相應的 二檔,手動從二檔 刪除OuterClassPrivate的所有定義和改變平普爾成員的聲明。
例如:
共享庫的第一版本
module pimpl.mylib;
class PimplTest
{
this()
{
mImpl = new PimplTestPrivate();
}
~this()
{
}
string sayWhat(string what)
{
return mImpl.ku ~ " " ~ what;
}
private class PimplTestPrivate
{
string ku = "Ku!!1";
}
private PimplTestPrivate mImpl;
}
測試應用:
module main;
import std.stdio;
import pimpl.mylib;
void main()
{
PimplTest t = new PimplTest();
writeln(t.sayWhat("?"));
}
共用MYLIB可以內置下面的方式(在Linux下):
$ dmd -H -c mylib.d -fPIC
$ dmd -ofmylib.so mylib.o -shared -defaultlib=libphobos2.so -L-rpath=/path/to/where/shared/phobos/library/is
然後編輯genereated二檔:
// D import file generated from 'mylib.d'
module pimpl.mylib;
class PimplTest
{
this();
~this();
string sayWhat(string what);
// NOTE this
private Object mImpl;
}
編譯測試itsel
$ dmd -c main.d /path/to/first/version/of/mylib.di
$ ln -s /path/to/first/version/of/mylib.so .
$ dmd main.o -L-l:mylib.so -defaultlib=libphobos2.so -L-rpath=/path/to/where/shared/phobos/library/is:.
$ ./main
Say: ?
然後我們改變MYLIB:
module pimpl.mylib;
import std.conv;
class PimplTest
{
this()
{
mImpl = new PimplTestPrivate();
}
~this()
{
}
string sayWhat(string what)
{
return mImpl.getMessage1(mImpl.getValue(), what);
}
private class PimplTestPrivate
{
int getValue()
{
return 42;
}
string ku = "Ku!!1";
string getMessage1(int x, string y)
{
return "x = " ~ to!(string)(x) ~ ", " ~ y;
}
double pi = 22.0/7.0;
}
private PimplTestPrivate mImpl;
}
編譯並替換二進制共享對象(所以文件)的第一個版本的mylib剛建成一個。運行測試應用程序不能崩潰,但輸出會有所不同。
這將是鏈接器的責任,以驗證內存佈局的假設,因爲這是唯一知道所有這些 –
我認爲這是不正確的。數據結構不存儲到目標文件。鏈接器不知道類型。 –
但編譯器不需要知道'.d'和'.di'文件 –