Статические функции области видимости C ++

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

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

Соответствует ли мое использование тому, почему эта функция существует? Или я угоняю концепцию, которая предназначена для чего-то другого?

0

Решение

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

2

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

Я делаю аналогичную вещь, когда имеет смысл иметь функции и / или данные, которые не являются частью интерфейса класса, а скорее деталями реализации.

Но я не использую ключевое слово static. Вместо этого я помещаю функции и / или данные в безымянное пространство имен.

1

Во-первых, термин, который вы ищете внутренняя связь. Ваш вопрос действительно должен быть: «Какие объекты должны иметь внутреннюю связь?» static Ключевое слово, или, альтернативно, безымянные пространства имен, являются просто механизмами реализации для достижения внутренней связи.

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

Типичный пример такой:

my_lib.hpp:

#ifndef H_MY_LIB
#define H_MY_LIB

namespace foo
{
void do_an_awesome_thing(void * p, std::size_t n);
}

#endif

my_lib.cpp:

#include "my_lib.hpp"
namespace foo
{
namespace
{
void helper(void * p) { /* ... */ }
bool aux(std::size_t n, float f) { /* ... */ }

constexpr char usage[] = R"(This is how you do it...)";
constexpr float some_factor = 1.25;
}

void do_an_awesome_thing(void *p, std::size_t n)
{
if (!aux(n, some_factor)) { LOG_AND_DIE(usage); }
helper(p);
}
}

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

Расположение безымянного пространства имен — дело вкуса; вы можете иметь его либо внутри обычного пространства имен, либо на верхнем уровне. Эффект тот же.

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