リンクから:「エクスポートされたC++クラスのサイズを決して変更しないでください」という問題。
解決策:「トリックは、単一のポインターを格納するだけで、ライブラリのすべてのパブリック クラスのサイズを一定に保つことです。このポインターは、すべてのデータを含むプライベート/内部データ構造を指します。」.
クラスが lib の消費者に表示されない限り、自由に D ポインタを使用しなくてもかまいません。「消費者に表示される」とは、「消費者コードに含まれることを意図したヘッダーの宣言によって完全な定義が利用可能になる」ことを意味します。おそらく、パブリック/プライベートという用語は、ここでは「セマンティック オーバーロード」に苦しんでいます。「公開」/「不透明」を使用しましょう ( **脚注を参照) 。
あなたの例では、B
との両方C
が公開されているため、「ポインターのみ」で利用できる必要があります。
myLib
クラスについても同様です。さらに悪いmyLib
ことに、コンストラクターが であるため、 のインスタンスを値で取得できますpublic
。これは、次のようなことができることを意味します。
myLib libObj;
libObj.getB(4)->getC(2)->getVar();
myLib
. _
消費者にファクトリメソッドを強制的に実行させてmyLib
(または「シングルトン」を使用して)インスタンスを取得することをお勧めします。次の行に何か:
class myLib {
private:
myLib() {
}
public:
static myLib* createInstance() {
return new myLib();
}
};
**「exposed/opaque 宣言」の例として -class B
はライブラリ コンシューマーに公開されます (これはB
-s が.. えーと... プライベート パーツを持っていることを知っています) がclass M
、コンシューマーについてはそれが存在することだけを知っており、ライブラリはそれへのポインタを提供します:
ファイル「myLib.hpp」
// M_type is a pointer to a class and that's all you,
// the consumer, need to know about it. You give me an M_type
// and ask specific questions about it and you'll
// get the details or access to data I choose to
// make available to you
typedef class M * M_type;
// Dear the library consumer, this class is public to you.
// You know I'm keeping a list of M_type, even if you also know
// you'll never get you hands directly on that list, because
// it has a private access. But having this information,
// **you can compute the sizeof(B)**.
class B {
public:
B();
M_type getM(int n);
const M_type getM(int n) const;
// that is one of the "questions" you can ask about an M_type
const char* getMLabel(const M_type var) const;
// I'm providing you with access to something that allows
// you to modify the amount stored by an M_type,
// even if you don't know (and never will) how
// I'm storing that amount
int& getMAmount(M_type var);
// You don't need to know how to create M-s, I'll
// be doing it for you and provide the index of the created
// M_type. Ask me with getM to get that pointer.
inr registerM(const char* label, int amount);
private:
QList<M_type> ems;
};
ライブラリ コードの奥深くに、何が何でclass M
あるかを定義するヘッダーが存在しmyLib.cpp
、それをインクルードしますが、そのヘッダーはライブラリをコンパイルするためだけに使用され、myLibバイナリリリースでは決して提供されません。そのclass M
ため、ライブラリの利用者にとっては (公開されているのではなく) 不透明です。