Условные функции членов

Какова рекомендация относительно условного определения функций-членов в classе C ++? (Вопрос сосредоточен вокруг ограничения внешнего воздействия некоторых classов в DLL – особенно когда эти classы передаются в качестве параметра). Очевидно, это не то, что вы хотите сделать с данными, но функции должны быть в порядке, не так ли?

Например:

class A { public: void func1(); #ifdef _CONDITION_ void func2(B b); #endif }; 

Отредактировано: Добавлен публичный модификатор, чтобы избежать путаницы.

Как правило, если вы не хотите выставлять части экспортируемого classа, вам следует рассмотреть возможность не подвергать class classу, а вместо этого предоставлять абстрактный интерфейс, на который наследуется ваш class.

например.

 class AbstractExportedInterface { public: virtual void do_stuff() = 0; }; class HasStuffIDontWantToExport : public AbstractExportedInterface { public: void do_stuff(); void do_other_stuff_that_i_dont_export(); }; 

то вы будете действовать исходя из предположения, что вы предоставляете пользователю HasStuffIDontWantToExport * пользователю DLL, и у них есть только заголовки для AbstractExportedInterface.

EDIT: ответ на первый комментарий

Если у вас есть некоторые типы (сторонние или другие), которые вы хотите, чтобы ваш клиент из DLL мог каким-то образом использовать, но вы не хотите, чтобы у них был полный доступ к этим типам, и у вас нет гибкости в использовании прямая иерархия наследования для создания абстрактного интерфейса. Возможно, вы сможете использовать шаблон pimpl для создания прокси-интерфейсов для каждого из типов, которые вы хотите, чтобы ваш клиент имел ограниченное использование?

например.

 class ExportedAbstractProxyObject { public: virtual void do_stuff() = 0; }; #include <3rdPartyType.h> class ProxyObject { public: void do_stuff() { pimpl_.actually_do_stuff(); } private: 3rdPartyType pimpl_; }; class ExportedAbstractProxyOtherObject { public: virtual void do_stuff_with_thing(ExportedAbstractProxyObject* thing) = 0; }; class ProxyOtherObject { public: void do_stuff_with_thing(ExportedAbstractProxyObject* thing) { thing->do_stuff(); } }; 

Таким образом, вы можете с радостью экспортировать любые интерфейсы, которые вам нравятся, и полностью скрывать реализацию и сторонние типы внутри вашей DLL. Недостатком является то, что вы, очевидно, должны создать все эти интерфейсы прокси-объектов.

Не совсем уверен, что вы просите, но если функции-члены предназначены для того, чтобы быть закрытыми для classа, используйте ключевое слово «private:», чтобы сделать их закрытыми.

Если вместо этого они предназначены для использования другими classами в контексте модуля, в котором живет этот class, но вы не хотите, чтобы внешние субъекты знали о них, сделайте их общедоступными, но выведите class из базового classа «interface», и выставить этот базовый class интерфейса внешним объектам.

Обычно это делается с использованием объявлений public / protected / private и, возможно, friend s, а не условий препроцессора. Но в одной программе я написал, где было больше проблемы объявить определенный набор функций как частных или защищенных (из-за количества автономных функций, которые нуждались в доступе к ним), я префикс псевдо-частной функции имена с подчеркиванием (вместе с четкими комментариями, объясняющими почему), чтобы дать понять читателю, что эти функции не предназначены для общего использования.

Вы говорите, что хотите предотвратить видимость некоторых classов, но ваш пример скрывает только один метод.

Если class не является частью «общедоступного» интерфейса вашей DLL, вам не нужно публиковать заголовок. Например:

 // foo.h class Bar; class Foo { private Bar* _bar; ... } 

Здесь «Бар» является частью реализации, поэтому нет необходимости отправлять свой заголовок. Если Bar используется только Foo, вы также можете определить его в области private / protected в Foo.