共享库中的D指针和组合类

时间:2016-08-29 05:53:08

标签: c++ shared-libraries qt5 composition d-pointer

我在Qt5 C ++中创建了一个共享库。为了允许将来更新保留二进制兼容性,我想使用d指针技术。但是,当有一个类的组合时,我不知道如何应用它。我找到的例子,包括一个here,只解释了类继承的情况。我的问题是

  

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

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

myLib.h

#include "B.h"

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

private:
        QList<B *> m_b;
}

B.h

#include "C.h"

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

C.h

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

主应用中的某个地方:

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

1 个答案:

答案 0 :(得分: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将有... ahem ...私有部分),但约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对于库消费者来说是不透明的(而不是暴露的)。