2015-04-08 4 views
0

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

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

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

ответ

2

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

1

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

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

1

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

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

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

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); 
    } 
} 

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

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

+0

Отличное объяснение. Благодаря! – DigitalEye

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