C ++ с использованием пространства имен в исходных файлах - PullRequest
5 голосов
/ 08 ноября 2010

Скажем, я делаю проект, и у меня есть большинство проектов в пространстве имен с именем Project. Я определяю класс внутри пространства имен Project с именем MainProject.

В исходном файле для реализации класса я делаю «использование пространства имен Project;» или мне нужно обернуть его в гнездо 'Project namespace {...}'?

Ответы [ 4 ]

7 голосов
/ 08 ноября 2010

С учетом заголовка "n.h":

namespace n{
  extern void f();
}

Следующее не определяет f() в пространстве имен n (с этого момента я буду называть его n::f:

#include "n.h"
using namespace n;

void f(){ }

Если вы попытаетесь сослаться на n::f в любом месте, вы получите ошибку во время соединения. Выше определено f в глобальном пространстве имен. Это определяет n::f:

#include "n.h"
void n::f(){ }

Это также делает:

#include "n.h"
namespace n{
  void f(){ }
}

но имеет недостаток: если вы неправильно введете имя или подпись, вы добавите новую функцию в пространство имен и оставите void n::f() неопределенным, что приведет к полусумной ошибке времени соединения.

Когда участвуют классы, все немного по-другому:

namespace n{
  class c{
    void f();
  };
  extern c operator + (const c&, const c&); // I'll use Matthieu M.'s example
}

Это будет хорошо, потому что нет глобального c:

#include "n.h"
using namespace n;
void c::f(){ }

Но следующее вызовет ошибку времени соединения, если вы попытаетесь добавить два символа c по той же причине, что и при первой попытке определения n::f():

#include "n.h"
using namespace n;
c operator + (const c &a, const c &b){ /* blah blah */ } // define global +

Этот сценарий также вызовет ошибку времени соединения (или, возможно, даже ошибку компиляции, в зависимости от того, где определено ::c::f):

class c{ // a global c, defined in some header somewhere
  void f();
};

#include "n.h"
using namespace n;
void c::f(){ } // define the global c::f (a possible redefinition) and n::c::f remains undefined!
3 голосов
/ 08 ноября 2010

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

2 голосов
/ 08 ноября 2010

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

1 голос
/ 08 ноября 2010

Существуют (тонкие) проблемы с синтаксисом using namespace xxx;. Среди которых имя сталкивается ...

В общем, лучше НЕ использовать его. Я бы рекомендовал повторно открыть пространство имен, а не добавлять идентификаторы к имени пространства имен, но это скорее вопрос вкуса.

Пример тонкой проблемы:

// header
namespace foo
{
  struct Bar
  {
    explicit Bar(int i);
    int x;
  };
  Bar operator+(Bar lhs, Bar rhs);
}

// source
#include "the header here"

using namespace foo;

Bar operator+(Bar lhs, Bar rhs)
{
  return Bar(lhs.x + rhs.x);
}

, что вызывает ошибку компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...