1

我正在 Qt5 C++ 中创建一个共享库。为了让未来的更新保持二进制兼容性,我想使用 d-pointer 技术。但是,当有类的组合时,我不知道如何应用它。我找到的示例,包括此处的示例,仅说明了类继承的情况。我的问题是

我是否需要为库中的每个类(myLib、B 和 C)或只为主要类(myLib)创建一个相应的私有类,以及以后如何访问它们?

这是我的设置和没有私有类的所需功能:

我的库

#include "B.h"

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

private:
        QList<B *> m_b;
}

溴化氢

#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-pointerless。通过“向消费者展示”,我的意思是“通过标题中的声明提供了它们的完整定义,这些声明应该包含在消费者代码中”。也许公共/私有术语在这里受到“语义过载”的影响,让我们使用“暴露”/“不透明”(见**脚注)

在您的示例中,两者BC都已公开,因此它们必须“仅通过指针”可用。

上课也是如此myLib。更糟糕的是: 的实例myLib可以通过值获得,因为构造函数是public. 这意味着我可以执行以下操作:

myLib libObj;
libObj.getB(4)->getC(2)->getVar();

这将使得未来版本的myLib.


我建议强迫消费者通过工厂方法来获取myLib(或使用“单例”)的实例。有点像:

class myLib {
private:
  myLib() {
  }

public:

  static myLib* createInstance() {
    return new myLib();
  }
};

**作为示例“暴露/不透明声明” -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 MmyLib.cpp包含它,但该头文件将仅用于编译库,并且从未与 myLib二进制版本一起提供。因此,class M对于图书馆消费者来说是不透明的(与暴露相反)。

于 2016-08-29T06:16:58.697 回答