Из связанной: Проблемы "Никогда не изменить размер экспортированного класса C++".
Решение: «Хитрость заключается в том, чтобы сохранить размер всех общедоступных классов константы библиотеки, сохраняя только один указатель. Этот указатель указывает на частную/внутреннюю структуру данных, которая содержит все данные».
Пока ваш класс не показан потребителям вашей библиотеки, не стесняйтесь идти D-pointerless. Под «показанным потребителям» я имею в виду «с их полным определением, доступным декларациями в заголовках, которые должны быть включены в код потребителя». Возможно, условия государственные/частные страдают от «семантической перегрузки» здесь, давайте использовать «выставлены»/«непрозрачные» (см ** сноска)
В вашем примере, как B
и C
подвергаются, поэтому они должны быть доступны «только указателями».
То же самое касается myLib
класс. Что еще хуже: экземпляры myLib
могут быть получены по значению, потому что конструктор public
. Это означает, что я могу сделать что-то вроде:
myLib libObj;
libObj.getB(4)->getC(2)->getVar();
, который сделает невозможным иметь «падение замен, ни перекомпиляций необходимых» из будущих выпусков myLib
.
Я предлагаю заставлять потребителей проходить заводской метод для получения экземпляров myLib
(или с помощью «singleton»).Что-то на линии:
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
непрозрачен (в отличие от выставленного) для потребителя библиотеки.
Из связанного: проблема «Никогда не изменяйте размер ** экспортированного класса C++ **». Решение: «Хитрость заключается в том, чтобы сохранить размер ** всех открытых классов ** константы библиотеки, только сохраняя единственный указатель. Этот указатель указывает на частную/внутреннюю структуру данных, которая содержит все данные». –