Створення простору імен C ++ у заголовку та джерелі (cpp)


88

Чи існує якась різниця між загортанням вмісту файлу заголовка та файлу cpp у простір імен чи обгортанням лише вмісту заголовка, а потім використанням простору імен у файлі cpp?

Під різницею я маю на увазі будь-яке покарання за продуктивність або дещо іншу семантику, яка може спричинити проблеми або щось, що мені потрібно знати.

Приклад:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

VS

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

Якщо немає різниці, яка форма є кращою і чому?

Відповіді:


37

Простір імен - це просто спосіб керувати підписом функції, щоб вони не конфліктували. Хтось віддає перевагу першому, а хтось другому варіанту. Обидві версії не впливають на продуктивність часу компіляції. Зверніть увагу, що простори імен - це просто сутність часу компіляції.

Єдина проблема, яка виникає при використанні простору імен, це коли ми маємо однакові вкладені імена простору імен (тобто) X::X::Foo. Це робить більшу плутанину з ключовим словом або без нього.


55

Різниця у "просторі імен X" у "використанні простору імен X" полягає в тому, що в першому будь-які нові оголошення будуть знаходитися під простором імен, а у другому - ні.

У вашому прикладі немає нової декларації - отже, ніякої різниці, отже, жодного бажаного способу.


Це залежить від проекту та стилю. Часто існує один основний простір імен для завантаження файлів в модулі, і другий стиль має сенс.
Ніколас Вілсон,

8

Не застосовується покарання за продуктивність, оскільки отриманий результат може бути однаковим, але розміщення вашого Fooу просторі імен неявно вносить неоднозначність, якщо у вас є Foos в різних просторах імен. Ви дійсно можете отримати свій код коду. Я рекомендую уникати використання usingдля цієї мети.

І у вас {після цього заблукав using namespace;-)


Я б не назвав це бездомним, оскільки воно відповідає завершенню }в самому кінці. Однак я б назвав цю пару брекетів зайвою;)
blubberdiblub

@blubberdiblub, запитання було відредаговано, якщо ви перевірили оригінальну версію, ви б назвали його бездомним ;-)
Майкл Крелін - хакер

1

Якщо компілює і другий, відмінностей не повинно бути. Простори імен обробляються під час компіляції і не повинні впливати на дії середовища виконання.

Але що стосується питань дизайну, друге - це жах. Навіть якщо він компілюється (не впевнений), це взагалі не має сенсу.


1
Я не думаю, що це компілюється, але не тому, що є різниця, а тому, що є бродяга {;-)
Майкл Крелін - хакер

Різниця полягає у тому, що Foo :: TheFunc () оголошено у глобальному просторі імен, тоді як він визначений у просторі імен X.
bert-jan

1

Foo :: TheFunc () знаходиться не у правильному просторі імен у справі VS. Використовуйте 'void X :: Foo :: TheFunc () {}' для реалізації функції у правильному просторі імен (X).


Питання трохи застаріле, але чи знаєте ви, які наслідки від цього? тобто чи не зіткнетеся з якимись проблемами з тим, як його справа VS оголошує функції у просторі імен, але визначає їх поза ним?
Адам Гудвін,

1

Якщо ви все-таки обернете лише вміст .h, вам доведеться писати за допомогою простору імен ... у файл cpp, інакше ви кожен раз працюєте над дійсним простором імен. Зазвичай ви обертаєте файли .cpp та .h, інакше ви ризикуєте використовувати об'єкти з іншого простору імен, що може створити багато проблем.


0

Я думаю, що тут слід правильно використовувати простір імен для масштабування.

namespace catagory
{
    enum status
    {
      none,
      active,
      paused
    }
};

void func()
{
    catagory::status status;
    status = category::active;
}

0

Якщо ви намагаєтеся використовувати змінні від однієї до іншої, я б рекомендував їх екстерналізувати, а потім ініціалізувати у вихідному файлі так:

// [.hh]
namespace example
{
   extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
   int a, b, c;
}
// Then in the function below, you can init them as what you want: 
void reference
{
    example::a = 0;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.