должны ли "вспомогательные функции" класса C ++ быть членами, свободными или свободными от пространства имен? - PullRequest
15 голосов
/ 18 июля 2009

Итак, у меня есть класс. Это полезный класс. Мне очень нравится. Давайте назовем это MyUsefulClass. MyUsefulClass имеет публичный метод. Давайте назовем это processUsefulData(std::vector<int>&).

Теперь предположим, что processUsefulData действительно делает две вещи, и я хочу реорганизовать это из этого:

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data)
{
    for (/*...*/)
    {
        for (/*...*/)
        {
            // a bunch of statements...
        }
    }

    for (/*...*/)
    {
        for (/*...*/)
        {
            // a bunch of other statements...
        }
    }
    return data;
}

Теперь я хочу разделить эти обязанности и переписать код как

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data)
{
    doProcessA(data, dataMember_);
    doProcessB(data, otherDataMember_);
    return data;
}

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

Ответы [ 7 ]

11 голосов
/ 18 июля 2009

Обычно я делаю вспомогательные подпрограммы «свободными» подпрограммами в автономном пространстве имен, если это возможно. Таким образом, я не усложняю интерфейс (в файле * .h) вещами, о которых клиентам не нужно беспокоиться.

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

7 голосов
/ 18 июля 2009

Свободная функция / функция-член

Я бы сделал их свободными функциями, возможно (им не нужен доступ к внутренностям класса). Если они работают с набором атрибутов или нуждаются в доступе к другим членам, сделайте его функцией-членом.

Доступ

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

Если другой код получит пользу от использования кода, опубликуйте его в интерфейсе. Это означает, что он должен быть защищен, если он является членом, или иметь свободную функцию, доступную через заголовок в именованном пространстве имен (или глобальном пространстве имен).

3 голосов
/ 18 июля 2009

Я обычно делаю их protected или private функциями-членами. Это будет зависеть от того, планируете ли вы получить класс и переопределить функции.

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

2 голосов
/ 18 июля 2009

Тот факт, что вы упоминаете о свободных функциях, заставляет меня полагать, что «куча других операторов» не требует доступа к данным класса. Если так, сделайте их свободными. Это уменьшает сложность заголовка вашего класса, плюс свободные функции легче использовать в стандартных алгоритмах (может быть, std :: for_each, так как вы все равно работаете с векторами?).

2 голосов
/ 18 июля 2009

Всегда предпочитайте бесплатные функции членам. Смотрите мой ответ здесь , чтобы узнать почему.

0 голосов
/ 18 июля 2009

Функции-члены, безусловно, если исходная функция имела смысл как функция-член.

Приватное / защищенное IMHO зависит от того, как используется их функциональность: если исходная функция все еще требуется, и рефакторинг предназначен исключительно для того, чтобы сделать код более чистым, то сделайте их защищенными или приватными и вызовите их из обычной функции. Вы получаете рефакторинг, но таким образом сохраняете общедоступным интерфейс класса.

0 голосов
/ 18 июля 2009

Подумайте о сфере. Будут ли эти функции использоваться в другом классе или в другом месте? Должны ли они быть общедоступными?

Мне кажется, они должны быть частными функциями-членами, но все зависит от вашей общей структуры охвата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...