Вложенные пространства имен, исправьте проблемы с дизайном статической библиотеки

В настоящее время я занимаюсь разработкой довольно большой статической библиотеки, которая будет использоваться некоторыми инструментами, когда она будет завершена. Теперь, когда этот проект несколько больше, чем все, чем я занимался до сих пор, я понял, что пора подумать о хорошей структуре для проекта. Использование пространств имен - один из таких логических шагов.

Мой текущий подход состоит в том, чтобы разделить библиотеку на части (которые не являются автономными, но их цель требует такого разделения). У меня есть «основная» часть, которая теперь просто содержит некоторые очень общие определения типов и константы (используемые многими различными частями библиотеки). Другими частями являются, например, некоторые «утилиты» (хэш и т. Д.), Ввод-вывод файлов и так далее. Каждая из этих частей имеет собственное пространство имен. Я почти закончил «утилиты» и понял, что мой подход, вероятно, не самый лучший. Проблема (если мы хотим это так называть) в том, что в пространстве имен utils мне нужно что-то из пространства имен core, что приводит к включению файлов заголовков ядра и многих директив using.

Так что я начал думать, что это, наверное, нехорошо и нужно как-то менять. Моя первая идея - использовать вложенные пространства имен как что-то вроде core :: utils. Поскольку это потребует серьезного рефакторинга, я хочу сначала спросить здесь. Что вы думаете? Как бы вы с этим справились? Или в более общем плане: как правильно спроектировать статическую библиотеку с точки зрения пространств имен и организации кода? Если есть какие-то рекомендации или статьи по этому поводу, пожалуйста, прочтите их тоже. Спасибо.

Примечание: я совершенно уверен, что хороших подходов больше, чем один. Не стесняйтесь размещать свои идеи, предложения и т. Д. Поскольку я разрабатываю эту библиотеку, я хочу, чтобы она была действительно хорошей. Наша цель - сделать его максимально чистым и БЫСТРЫМ. Единственная проблема в том, что мне придется интегрировать МНОГО существующего кода и реорганизовать его, что действительно будет болезненным процессом (вздох) - вот почему хорошая структура так важна)


person PeterK    schedule 11.06.2010    source источник


Ответы (2)


Что ж, я бы подумал, что в заголовке core.h у вас будет что-то вроде

#include <string>
#include <iostream>
namespace core
{
    typedef std::string mystring;
    #define mycout std::cout
}

И ни одной директивы using, чтобы предотвратить загрязнение глобального пространства имен. В заголовке utils.h вы должны использовать такие вещи, как:

#include "core.h"
namespace utils
{
    core::mystring stringfunction(core::mystring &stuff)
    {
        core::mystring result;
        // do stuff
        return result;
    }
}

Следовательно, нет mystring нигде, кроме core ::. Это включает в себя немного больше набора текста, но для этого нужны пространства имен, позволяя себе знать, откуда вы берете тип / функцию / класс.

ОБНОВЛЕНИЕ

Другая сторона истории примерно такая:

core.h заголовок, объявляющий материал в основном пространстве имен, как указано выше.

Заголовок utils.h, объявляющий материал в пространстве имен core :: utils, а затем оператор namespace utils = core::utils. Это делает два подхода идентичными для пользователя и позволяет вам писать такие вещи, как mystring вместо core::mystring в utils*.h заголовках и *.cpp файлах.

Примерно так для utils.h:

#include "core.h"
namespace core
{
    namespace utils
    {
        mystring stringfunction(mystring &stuff)
        {
            mystring result;
            // do stuff
            return result;
        }
    }
}
namespace utils = core::utils; // allow user to type utils::stringfunction

Это немного очищает пользовательский и библиотечный код.

person rubenvb    schedule 11.06.2010
comment
Это именно то, что у меня есть сейчас (директивы using находятся в файлах .cpp, я забыл об этом). Мне просто было интересно, будет ли в этом случае лучше вложение, поскольку основное пространство имен - это нечто фундаментальное, имена, которые будут использоваться в различных частях библиотеки. - person PeterK; 11.06.2010
comment
Я вижу, вы неправильно поняли ваш вопрос: s. Приведен пример вложенного пространства имен и решение проблемы;) - person rubenvb; 11.06.2010
comment
Спасибо, мне нравится ваше решение. Он как бы предлагает одно пространство имен для каждой библиотеки, что предлагал Нил, и в то же время позволяет хорошо разделить код. - person PeterK; 11.06.2010

Мой собственный подход - использовать одно пространство имен для каждой библиотеки. Я не думаю, что вложенные пространства имен приносят что-то на вечеринку, если вам не нравится печатать (на клавиатуре). Это сработало для меня без проблем.

person Community    schedule 11.06.2010