2012-02-06 3 views
5

Я определил некоторые функции (здесь не задействованы классы) во внешнем * .cpp файле, и, конечно, есть соответствующий * .h-файл.Shoud Я использую неназванные пространства имен в файлах реализации?

Некоторые из функций в файле * .cpp используются только только в этом * .cpp-файле нигде больше. Они даже не упоминаются в файле * .h.

Должен ли я помещать эти функции в неназванное пространство имен или они могут жить рядом с другими функциями? И если да, зачем мне нужно неназванное пространство имен? Я не вижу проблемы, так как эти функции не доступны извне.

+0

Почему бы просто не сделать их «статическими»? (как в статической функции C, а не в методе статического класса) –

+1

@JamesMcLaughlin: Ну, в C++ 03 'static' для этой цели не рекомендуется. Однако C++ 11 не отменяет его. Но «статические» и находящиеся в неназванном пространстве имен означают разные вещи. 'static' даст ему внутреннюю связь, поэтому функция не может использоваться для некоторых целей. –

+0

Спасибо за ваши предложения. Является ли какое-либо из этих решений статическим или нерегулярным пространством имен, рекомендованным или предпочтительным? – user1192880

ответ

9

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

Рассмотрим следующий пример:

// library.cpp 

// a "private" function here, in that it is not declared anywhere 
void f() {} 

namespace 
{ 
    // same as above, except within an anonymous namespace 
    void g() {} 
} 

// client.cpp 

void f(); 

int main() 
{ 
    // Can call f(), it's been declared and is now effectively "public" 
    f(); 

    // compilation error, this has no idea what g() is, it's not declared 
    // in any scope that can be resolved here 
    g(); 

    return 0; 
} 
+0

Спасибо! Я не знал об этой «функции». – user1192880

+0

Для этого используется 'static'. Анонимные пространства имен предоставляют эту функцию для классов и структур. –

+0

Является ли ключевое слово 'static' также защищенным от столкновения имен с другими функциями, которые могут существовать в других частях кода? Безымянное пространство имен будет. – Chad

1

Я думаю, если вы не хотите, чтобы эти функции можно увидеть снаружи объявить их как static.

+0

* «... видно из-за пределов ...» * - Из-за чего? Заголовок? Единица перевода? – jww

4

Ваш вопрос можно разделить на две части:

1. «Как я могу скрыть глобальные функции»

Один простой способ сделать это, является НЕ поставить заголовок функции в файле заголовка:

//============================ 
// Filename: "mylibrary.hpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
#ifndef MYLIBRARY_H_INCLUDED 
#define MYLIBRARY_H_INCLUDED 
//============================ 

namespace MyLibrary 
{ 
    void DoSomething(); 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

Полный код файла:

//============================ 
// Filename: "mylibrary.cpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
// self header include 
#include "mylibrary.hpp" 
//============================ 

namespace MyLibrary 
{ 
    void DoSomethingBefore() 
    { 
     // ... 
    } 

    void DoSomethingAfter() 
    { 
     // ... 
    } 

    void DoSomethingConfirmed() 
    { 
     // ... 
    } 

    void DoSomething() 
    { 
     DoSomethingBefore(); 
     DoSomethingConfirmed(); 
     DoSomethingAfter(); 
    } 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

Когда компилируется , вы получаете файл «mylibrary.o» или «mylibrary.obj». Вы можете предоставить его другим разработчикам: «mylibrary.hpp» плюс «mylibrary.obj», но без файла «mylibrary.cpp». Большинство компиляторов «plain c»/«C++» могут работать таким образом.

Есть другие способы, прочтите следующий раздел.

2. «Анонимные пространства имен, хорошая техника для скрытия глобальных функций?»

Техника «Анонимные пространства имен» - это еще один способ скрыть глобальные функции.

Существует аналогичный вопрос о:

Unnamed/anonymous namespaces vs. static functions

Но, лично я не рекомендую этот метод, как «любимый» ответ.

Пространства имен - одна из тех вещей, которые я хочу существовать с самого начала «чистого c» или «C++». Но «анонимные пространства имен» или «неназванные пространства имен» кажутся странными.

Это похоже на попытку скрыть что-то, а потом забыть, где вы его храните.

3 Дополнительные предложения

(а) я предлагаю использовать один основной НЕОБХОДИМЫХ, не обязательны, неанонимные имена каждого файл. Он может иметь вложенные дополнительные внутренние пространства имен. Каждое основное пространство имен должно иметь одинаковый идентификатор. как имя файла, но без расширения файла или суффикса файла.

(b) Избегайте анонимных пространств имен. Это похоже на хранение вещей на складе, без индекса.

(c) Используйте расширение файла или префикс файла в ваших заголовочных файлах, возможно, «.h» или «.hpp», даже если это файл C++. В стандарте указано, что C++ не должен использовать расширение файла или суффикс файла в файлах «C++», но их трудно идентифицировать или найти в файловой системе.

Удачи.

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