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

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

3 голосов
/ 16 апреля 2011

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

Например:

class A
{
public:
    void func1();

#ifdef _CONDITION_
    void func2(B b);
#endif    
};

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

Ответы [ 4 ]

2 голосов
/ 16 апреля 2011

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

например.

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.

РЕДАКТИРОВАТЬ: Ответ на первый комментарий

Если у вас есть некоторые типы (сторонние или иные), которые вы хотите, чтобы ваш клиент 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. Недостатком является то, что вам, очевидно, придется создавать все эти интерфейсы прокси-объектов.

2 голосов
/ 16 апреля 2011

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

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

0 голосов
/ 16 апреля 2011

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

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

// foo.h
class Bar;

class Foo
{
    private Bar* _bar;
    ...
}

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

0 голосов
/ 16 апреля 2011

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

...