来自链接:问题“永远不要更改导出的 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 将有.. 嗯......私人部分),但关于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
对于图书馆消费者来说是不透明的(与暴露相反)。