Свободная функция против функции-члена
В чем преимущество бесплатной функции (в анонимном пространстве имен и доступной только в одном исходном файле) и отправки всех переменных в качестве параметров в отличие от наличия функции частного класса, свободной от любых параметров и непосредственного доступа к переменным-членам? Спасибо!
Заголовок:
Class A {
int myVariable;
void DoSomething() {
myVariable = 1;
}
};
Источник:
namespace {
void DoSomething2(int &a) {
a = 1;
}
}
int A::SomeFunction() {
DoSomething2(myVariable); // calling free function
DoSomething(); // calling member fucntion
}
Если вы предпочитаете делать их членами, то что, если у меня есть случай, когда я сначала вызываю функцию, которая не имеет доступа к каким-либо переменным-членам, но эта функция вызывает другую функцию, которая обращается к члену. Должны ли они оба быть функциями-членами или бесплатными?
Ответы
Ответ 1
Одним из преимуществ функции, не являющихся членами в исходном файле похож на преимуществах Pimpl идиома: клиенты, использующие ваши заголовки, не должны перекомпилировать, если вы измените свою реализацию.
// widget.h
class Widget
{
public:
void meh();
private:
int bla_;
};
// widget.cpp
namespace {
void helper(Widget* w) // clients will never know about this
{ /* yadayada */ }
}
void widget::meh()
{ helper(this); }
Конечно, при написании такого текста helper()
может использовать только открытый интерфейс Widget
, поэтому вы мало выигрываете. Вы можете поместить объявление friend
для helper()
внутри Widget
, но в какой-то момент вам лучше перейти на полномасштабное решение Pimpl.
Ответ 2
см. этот вопрос: Эффективный С++ Item 23 Предпочитайте функции, отличные от членов, не являющихся членами для функций-членов
а также Функции членов С++ и бесплатные функции
Вы должны выбирать свободные функции, в той мере, в какой это способствует свободному соединению.
Рассмотрите возможность создания функции-члена только в том случае, если она работает на кистях вашего класса, и вы считаете, что она действительно привязана к вашему классу.
Это точка книги 101 С++ стандартов кодирования, которая заявляет, что предпочитает свободную функцию и статическую функцию над функциями-членами.
Несмотря на то, что это может считаться основанной на мнениях, это позволяет сохранить класс немного, и к отдельным проблемам.
В этом ответе говорится: "Причина этого правила заключается в том, что с помощью функций-членов вы можете слишком сильно полагаться на внутренности класса".
Ответ 3
Основным преимуществом бесплатных функций и функций-членов является то, что он помогает отделить интерфейс от реализации. Например, std::sort
не нужно ничего знать о базовом контейнере, на котором он работает, просто чтобы он предоставил доступ к контейнеру (через итераторы), которые предоставляют определенные характеристики.
В вашем примере метод DoSomething2
не способствует уменьшению связи, поскольку он все равно должен получить доступ к частному члену, передав его по ссылке. Совершенно очевидно, что просто сделать мутацию состояния в обычном методе DoSomething
.
Когда вы можете реализовать задачу или алгоритм с точки зрения открытого интерфейса класса, это делает его хорошим кандидатом для создания свободной функции. Скотт Мейерс обобщает здесь разумный набор правил: http://cpptips.com/nmemfunc_encap