Должен ли С++ класс "вспомогательные функции" быть свободным или свободным, или пространство имен 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 зависит от того, как их функциональность используется: если исходная функциональная операция по-прежнему требуется, и рефакторинг предназначен исключительно для того, чтобы сделать очиститель кода, сделать их защищенными или частными и вызвать их из обычной функции. Вы получаете рефакторинг, но поддерживаете открытый интерфейс класса таким образом.