Наилучшая практика использования директив

#c #namespaces

#c #пространства имен

Вопрос:

Есть ли какая-либо функциональная или оптимизационная разница между следующим?

 // SomeClass.cpp
#include "SomeClass.h"
#include "SomeOtherClassInSomeClassNamespace.h"

using namespace SomeClassNamespace;

SomeClass::SomeClass() {}

void SomeClass::SomeFunc() 
{
    // uses some stuff in SomeClassNamespace not defined  in SomeClass.h
}
  

или

 // SomeClass.cpp
#include "SomeClass.h"
#include "SomeOtherClassInSomeClassNamespace.h"

namespace SomeClassNamespace
{
    SomeClass::SomeClass() {}

    void SomeClass::SomeFunc() 
    {
        // uses some stuff in SomeClassNamespace not defined  in SomeClass.h
    }
}
  

Комментарии:

1. @Bala R не совсем — я знаю возможные опасности директивы using, но это конкретный случай, о котором там не говорилось

Ответ №1:

Есть ли какая-либо функциональная разница между следующим?

Пока объединенные области разрешаются, как ожидалось, тогда нет.

Есть ли какая-либо разница в оптимизации между следующим?

Время выполнения или двоичный размер? Нет.

Если вы хотите оптимизировать сборку, то дополнительная сложность будет введена через using и / или путем повторного открытия пространства имен.

Я не использую первое, потому что разрешения могут быть проблематичными.

Я не использую последнее, потому что легко получить новые объявления.

То, как я его использую:

 namespace {
  // ... private stuff
}

SomeClassNamespace::SomeClass::SomeClass() {}
...
  

это немного многословно, но быстро разрешает определения с их объявлениями, снижает вероятность коллизий, может уменьшить количество ошибок программиста и может уменьшить размер двоичного файла, если определения в анонимном пространстве имен в конечном итоге экспортируются (в случае, если вы также используете частные реализации). Конечно, также имеет смысл сохранить ваши внутренние элементы («некоторые вещи в SomeClassNamespace, не определенные в SomeClass.h») в правильном пространстве имен (при условии, что они используются в нескольких TU).

Комментарии:

1. Да, я использую неназванные пространства имен в любом случае. Другая возможность, которая иногда соответствует моим потребностям, — это объявление using вместо этого. using SomeClassNamespace::SomeClass; Таким образом, мне не нужно ставить перед каждым определением префикс SomeClassNamespace:: . Досада заключается в том, что когда у меня есть 5 или 6 классов в системе , все в пространстве имен, я не хочу писать кучу объявлений using в верхней части каждого cpp.

2. @Dave может быть, вы хотите попробовать псевдонимы пространства namespace SMClsNs = SomeClassNamespace; имен или определения типов в своих внутренних файлах? в течение некоторого времени меня не беспокоили полностью определенные области…

3. Они не беспокоят меня в пользовательском коде, они беспокоят меня при реализации класса в этом пространстве имен

Ответ №2:

Это единственный раз, когда я когда-либо использую using namespace X;

И я удостоверяюсь, что в файле есть только определения классов внутри пространства имен X (и только по одному классу за раз).

Единственная причина, по которой я делаю это таким образом, заключается в том, что (и личное мнение) я думаю, что это облегчает чтение в целом. И он документирует пространство имен, с которым мы работаем, в одной строке вверху (особенно если это многоуровневое вложенное пространство имен).

Комментарии:

1. Из любопытства, что вы делаете, когда класс находится во вложенном пространстве имен? using namespace оба пространства имен или только самое нижнее?

2. @David: Взгляните на мой код: github.com/Loki-Astari/ThorsSerializer/tree/master/src /…

Ответ №3:

namespace { Чтобы быть последовательным, вы должны делать отступы во всем файле, что уменьшит объем фактического кода, который вы можете поместить в строку, прежде чем он исчезнет из поля зрения.

У вас нет этой проблемы с using оператором.

Вы также можете получить более запутанное сообщение об ошибке с namespace { опцией, потому что закрывающая скобка для пространства имен может закрыть что-то еще, что не было закрыто должным образом. В конечном итоге вы можете получить запутанные сообщения о том, что в пространстве имен отсутствует закрывающая фигурная скобка.

Кроме этого, я не знаю никакой разницы.

Комментарии:

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

2. @Dave, да, но это несоответствие меня беспокоит. Кажется, немного лучше использовать using namespace . Действительно незначительно, но поскольку между двумя формами почти нет разницы…