13

В чем преимущество бесплатной функции (в анонимном пространстве имен и доступной только в одном исходном файле) и отправки всех переменных в качестве параметров в отличие от функции частного класса, не содержащей никаких параметров и доступ к переменным-членам напрямую? Благодаря!Свободная функция против функции-члена

Заголовок:

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

Можете ли вы хотя бы написать код, который * пытается * скомпилировать? – Shoe

+0

@StephaneRolland нет, эта ссылка о публичном интерфейсе, а не о реализации – TemplateRex

+1

@TemplateRex позвольте мне настаивать, речь идет об использовании функций-членов или нет. Позвольте мне процитировать ответ: «Имея много и много методов, напрямую зависящих от внутренних элементов класса, малейшее изменение подразумевает полную переписку. Этого не должно быть». –

ответ

5

посмотреть на этот вопрос: Effective C++ Item 23 Prefer non-member non-friend functions to member functions , а также C++ Member Functions vs Free Functions

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

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

Это пункт книги 101 Стандарты кодирования С ++, который утверждает, что предпочитает свободную функцию и статическую функцию над функциями-членами.

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

В этом answer указано: «причина этого правила в том, что, используя функции-члены, вы можете слишком сильно полагаться на внутренности класса».

+0

Не проблема с функциями-членами, что они не сохраняют состояние каких-либо переменных или указателей внутри? Я имею в виду, когда свободная функция заканчивается, так что любые указатели и переменные, которые вы объявили в функции-члене ... –

+1

Не уверен, что я понимаю, что вы имеете в виду. Я бы исправил и перефразировал ваше предложение таким образом: не существует большой разницы между свободной функцией и методом. Мы могли бы упростить и сказать, что методы просто имеют доступ к другому входному параметру, который называется 'this' и который неявно передан и доступен внутри метода. Метод имеет ** Абсолютно ** никакого другого поведения, кроме бесплатных функций относительно объема жизни локальных переменных и указателей. –

9

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

// 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.

4

Основным преимуществом бесплатных функций и функций-членов является то, что он помогает отделить интерфейс от реализации. Например, std::sort не должен знать что-нибудь о базовом контейнере, на котором он работает, просто чтобы ему был предоставлен доступ к контейнеру (через итераторы), который обеспечивает определенные характеристики.

В вашем примере метод DoSomething2 не способствует уменьшению связи, поскольку он по-прежнему должен получить доступ к частному члену, передав его по ссылке. Совершенно очевидно, что просто сделать мутацию состояния в обычном методе DoSomething.

Когда вы можете реализовать задачу или алгоритм с точки зрения открытого интерфейса класса, это делает его хорошим кандидатом для создания свободной функции.Скотт Мейерс подытоживает разумный набор правил: http://cpptips.com/nmemfunc_encap

 Смежные вопросы

  • Нет связанных вопросов^_^