Должен ли С++ класс "вспомогательные функции" быть свободным или свободным, или пространство имен anon?

Итак, у меня есть класс. Это полезный класс. Мне очень нравится. Позвольте называть его 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;
}

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

Ответы

Ответ 1

Функция свободной функции/члена

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

Доступ

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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