Должен ли я использовать безымянные пространства имен в файлах реализации? - PullRequest
6 голосов
/ 06 февраля 2012

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

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

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

Ответы [ 3 ]

14 голосов
/ 06 февраля 2012

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

Возьмите следующий пример:

// 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;
}
4 голосов
/ 06 февраля 2012

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

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. «Являются ли анонимные пространства имен хорошей техникой для сокрытия глобальных функций?»

Техника «Anonymous Namespaces» - это еще один способ скрытия глобальных функций.

Есть похожий вопрос:

Безымянное / анонимное пространство имен и статические функции

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

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

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

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

(a) Я предлагаю использовать одно основное ТРЕБУЕМОЕ , а не необязательное, неанонимное пространство имен для каждого файла. Это могут быть вложенные дополнительные внутренние пространства имен. Каждое основное пространство имен должно иметь одинаковый идентификатор. в качестве имени файла, но без расширения файла или суффикса файла.

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

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

Удачи.

1 голос
/ 06 февраля 2012

Полагаю, если вы не хотите, чтобы эти функции были видны извне, объявите их как static.

...