2012-06-07 3 views
14

Предположим, я объявил функцию (или класс, не имеет значения) в файле заголовка, который является частью пространства имен Foo:Рекомендации: использование пространства имен или повторное открытие пространства имен?

namespace foo 
{ 
    void bar(); 
    … 
} 

В течение долгого времени я вновь открыть пространство имен, когда я определяли функцию в файле CPP:

namespace foo 
{ 
void bar() 
{ 
    doSomething(); 
    … 
} 
} 

это потому, что я узнал об этом так и он был использован в проекте я работал. Я никогда на самом деле, хотя об этом до недавнего времени, когда я наткнулся на проект, который использовал используя директиву вместо:

using namespace foo; 

void bar() 
{ 
    doSomething(); 
    … 
} 

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

void foo::bar() 
{ 
    doSomething(); 
    … 
} 

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

+3

Я бы сказал, что это вопрос личных предпочтений.Я сам использую смесь как первой, так и последней из ваших альтернатив. –

+5

Я согласен, что это вопрос личных предпочтений. 'foo :: bar' повторяется, но greppable, хотя это может быть неуместно, если люди только ищут ваш источник с помощью среды IDE. –

+2

Это похоже на вопрос, лучше ли использовать вкладки или 4 пробела. ** Не потейте мелкие вещи. ** :) – LihO

ответ

13

Я думаю, что чистый способ повторно открывает пространство имен, и у меня есть аргументы, чтобы поддержать его:

  • с вашим вторым вариантом, с using директивой, не ясно, что вы «Реализация метода в этом пространстве имен. Вы могли бы также реализовать свободную функцию, которая использует что-то из пространства имен.
  • третий вариант обычно используется для реализации функций-членов класса. Если вы посмотрите непосредственно в файле cpp, неясно, что вы реализуете функцию из пространства имен, если не знаете, что существует пространство имен. Первое, что приходит в голову, это то, что вы реализуете функцию члена класса.
  • первый из них самый чистый. Вы открываете пространство имен и определяете внутри него функцию. Эта функция является частью пространства имен, и это реализация.
+0

Ваш второй маркер, кажется, говорит: «Я не делаю X, поэтому первое, что приходит на ум, - это Y». Y не обязательно приходит первым в голову людей, которые делают X, поэтому, как только вы следуете за соглашением, проблема исчезает. Кроме того, если вы не можете определить разницу между именами имен и именами классов, подумайте о выборе лучших имен; -p. –

+0

@SteveJessop Я не думаю, что это действительная точка. 'X :: foo()' - это * только * способ, которым вы можете определить метод класса (если только он не встроен). Если для пространств имен у вас есть альтернатива. Итак, зачем использовать два стиля для представления разных вещей, когда вы можете использовать разные стили с четким намерением? –

+1

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

6

Несмотря на то, что using namespace является самым ленивым (и, следовательно, самым заманчивым) решением, часто это не очень хорошая идея. Кроме того, что Лучиан говорит о неоднозначности объявлений функций (кто-то новый для проекта не знал бы, является ли это автономной функцией или одной в пространстве имен), и тот факт, что позже вы можете ввести имя в пространство имен, столкнувшись с одним из вас используя теперь, у меня есть еще одна причина, почему я бы предложил использовать третий метод.

Используя третий метод, вы указываете свой код более Консистенция. Если A находится внутри B, вы всегда определяете его с помощью A::B. Если A является классом и B функция в классе, вы должны написать type A::B(args). Если A является классом и B статическим членом, вы снова должны написать type A::B = value. Теперь A - это пространство имен, но это по-прежнему та же концепция: B определяется внутри A, поэтому более последовательно использовать A::B.

(Существует дополнительный бонус поиска способности, если ваш редактор, например, ВИМ)

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