C++ namespace. Как правильно работают namespace?

141
24 сентября 2019, 21:40

У меня есть файл A.h в котором есть код:

namespace Top 
 {
    namespace Inner
    {
       namespace Bottom {
          class ClassA { ... }
       }
    }
 }

А в другом файле B.h, похожий код:

namespace Top 
 {
    namespace Inner
    {
       namespace Bottom {
          class ClassB { ... }
       }
    }
 }

Мой вопрос.

Зачем в разных файлах описывать одинаковые имена namespace? Или во время компиляции или компоновки они как-то соединяются в один, и компилятор может понять, что если у нас в файле A и B есть одинаковые имена, то тогда это один и тот же namespace? У меня проект более 20 разных файлов с такими же названиями пространства имен, но с разными классами внутри некоторых. К тому же, если я захочу подключить к своему проекту dll, в которой у меня будет ClassC с такой же иерархией имен пространств, будет ли это считаться этим же namespace или уже другим? Зачем нужно дублировать имена пространств в разных файлах?

Этот вариант можно считать валидным?

#include "A.h"
#include "B.h"
void func()
{
    Top::Inner::Bottom::ClassA();
    Top::Inner::Bottom::ClassB();
}
Answer 1

Дублирование имени namespace в разных файлах позволяет достичь..

Кратко:

  1. Удобства навигации/ориентации в коде.
  2. Дополнение существующего пространства имен новыми возможностями.

Детальней:

Все мы люди, и все мы устроены так, что не можем держать в голове много вещей одновременно. Гораздо удобнее и для себя, и для других программистов вынести уже "готовые" более менее отлаженные участки кода в отдельный файл (так сказать подальше, с глаз долой), чтобы не держать их в голове (кроме того, существуют и правила, что именно можно и нужно выносить в файлы, но это уже отдельная тема). Что же тогда? Придется разделять неймспейс? Не придется, потому что в разных файлах можно прописать одно и тоже имя для namespace. Глянем, например, как это делается в Qt (этот код создается по умолчанию при создании формы/диалогового окна):

mainwindow.h

namespace Ui {
//--------^^
class MainWindow;
}
class MainWindow : public QMainWindow
{
    // поля и методы
};

aboutform.h

namespace Ui {
//--------^^
class AboutDialog;
}
class AboutDialog: public QDialog
{
    // поля и методы
};

Обратите внимание, что имя пространства имен одинаковое. Благодаря этой возможности дополняется существующее пространство имен (которое могло быть объявлено где-то ранее).

Кроме всего прочего, используя, как Вы сказали, дублирование имени, можно расширить уже существующее пространство имен без его перекомпиляции. Никто не запрещает Вам сделать вот так:

#include <iostream>
namespace std {
    const int my_custom_value = 999;
};
int main()
{
    std::cout << "My custom std value = " << std::my_custom_value << std::endl;
    return 0;
}

И получить на экране:

My custom std value = 999

А представьте, сколько это времени экономит, ведь нам не нужно пересобирать все пространство имен.

Answer 2

Это будет всё равно одно и то же пространство имён, вы всего навсего его дополняете, компилятор понимает, что это одно и то же, главное правильно обращаться к классам. "Зачем в разных файлах описывать одинаковые именна namespace?" Разницы практически нет, а вот целесообразно ли это, это уже решать вам. Ваш вариант считается валидным.

READ ALSO
Qt. Нужна версия 4.8.2

Qt. Нужна версия 4.8.2

История такаяПреподаватель рекомендовал версию qt 4

144
Баг в Box2D или неверный поворот объекта

Баг в Box2D или неверный поворот объекта

Пишу приложение которое визуализирует физику используя Box2DОбъект в виде квадрата перемещается по клику мыши

141
Как написать keylogger qt c++? [закрыт]

Как написать keylogger qt c++? [закрыт]

Нужно написать keylogger в qt c++Как это можно сделать? Какие библиотеки нужно подключать?

133
Qt 4.8.2. Qt Crearor выдает ошибки

Qt 4.8.2. Qt Crearor выдает ошибки

начал изучать QtПреподаватель дал готовый код калькулятора на 4

120