我在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();
答案 0 :(得分:1)
来自链接:问题“永远不要改变导出的C ++类的大小”。
解决方案:“诀窍是通过仅存储单个指针来保持库的所有公共类的大小。此指针指向包含所有内容的私有/内部数据结构数据。”。
只要您的课程没有向您的lib的消费者展示,请随意使用D-pointerless。 “向消费者展示”是指“通过消费者代码中包含的标题中的声明提供完整定义”。也许公共/私人这些术语在这里遭受“语义过载”,让我们使用'暴露'/'不透明'(参见 ** 脚注)
在您的示例中,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();
}
};
** 作为一个例子“暴露/不透明的声明” - 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
对于库消费者来说是不透明的(而不是暴露的)。