Стилизация не связанных с классом функций

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

1

Решение

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

// Your .cpp
namespace
{
void yourHelperFunction( void ) // only visible in the translation unit
{
...
}
}

//
Я хотел прокомментировать, потому что в настоящее время я возвращаюсь домой, но мне нужна более высокая репутация … возможно, я уточню свой ответ позже.

0

Другие решения

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

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

namespace
{
int myHelperFunc()
{
int result = 0;
....
return result;
}
}

...

bool MyClass::someMethod()
{
return 0 != myHelperFunc();
}

void MyClass::someOtherMethod()
{
if (0 == myHelperFunc())
{
for (int i = 0; i < 10; ++i)
std::cout << i << std::endl;
}
}

Это позволяет повторно использовать вспомогательную функцию, но позволяет избежать любых возможных конфликтов имен.

преимущества

  • Область действия ограничена одним файлом.
  • Нет вероятности конфликта имен с другими вспомогательными функциями в других файлах с таким же именем.

Недостатки

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

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

int MyClass::myStatefulHelperFunc()
{
int result = 0;

if (IsInitialized())
{
....
}
return result;
}

...

bool MyClass::someMethod()
{
return 0 != myStatefulHelperFunc();
}

void MyClass::someOtherMethod()
{
if (0 == myStatefulHelperFunc())
{
for (int i = 0; i < 10; ++i)
std::cout << i << std::endl;
}
}

преимущества

  • Область действия ограничена одним классом.
  • Доступ к классу состояния.
  • Может быть сделано виртуальным, позволяя производным классам переопределять помощника с помощью альтернативной реализации.

Недостатки

  • Должен быть объявлен в заголовочном файле.

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

HelperFunction.h

namespace ProjectHelpers
{

/**
*  \brief  Do helpful thing.
*
*  \return a helpful integer.
*/
int myHelperFunc();

}

преимущества

  • Легко доступны из любой точки кодовой базы.

Недостатки

  • Большое количество вспомогательных функций, совместно используемых несколькими классами / единицами перевода, может указывать на запах кода.

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

преимущества

  • Область действия ограничена одной функцией.
  • Может использоваться в нескольких местах внутри функции путем присвоения переменной.

Недостатки

  • Только C ++ 11 и более поздние версии.

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

0

По вопросам рекламы [email protected]