1

Qt5 C++ で共有ライブラリを作成しています。バイナリ互換性を維持しながら将来の更新を可能にするために、d-pointer 手法を使用したいと考えています。しかし、クラス構成がある場合の適用方法がわかりません。hereを含む私が見つけた例は、クラス継承の場合のみを説明しています。私の質問は

ライブラリ内の各クラス (myLib、B、および C) に対応するプライベート クラスを作成する必要がありますか?それとも、メインのクラス (myLib) のみに対応するプライベート クラスを作成する必要がありますか? また、後でそれらにアクセスする方法はありますか?

これが私のセットアップと、プライベート クラスのない目的の機能です。

myLib.h

#include "B.h"

class myLib;
{
public:
        myLib();
        B *getB(int n);

private:
        QList<B *> m_b;
}

Bh

#include "C.h"

class B;
{
public:
        B();
        C *getC(int n);
private:
        QList<C *> m_c;
}

チャンネル

class C;
{
public:
        C();
        int getVar();
private:
        int m_var;
}

そしてメインアプリのどこかに:

myLib *m_lib = new myLib();
int k = m_lib->getB(4)->getC(2)->getVar();
4

1 に答える 1

1

リンクから:「エクスポートされた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ため、ライブラリの利用者にとっては (公開されているのではなく) 不透明です。

于 2016-08-29T06:16:58.697 に答える