пространства имен — C ++ Должен ли я полностью определить тип моей переменной?

Я пытаюсь написать строки кода под 80 столбцов максимум. Таким образом, мне интересно, действительно ли полная квалификация моего типа переменной обязательна? Предполагая следующую реализацию:

//Baz.h
namespace loggingapi {
namespace attributes {
class Baz {};
}} // namespaces

// Bar.h
namespace loggingapi {
namespace attributes {
class Baz; // forward declare Baz.
}

class Biz {
int f(Baz* b);
};
} // namespaces

Чтобы объявить мой тип параметра функции, есть несколько способов?

  • а) int f(Baz* b);
  • б) ИЛИ int f(attributes::Baz* b);
  • в) ИЛИ int f(loggingapi::attributes::Baz* b);
  • г) ИЛИ int f(::loggingapi::attributes::Baz* b);

В приведенном выше списке, какие определения являются / являются более ясными / неоднозначными для компиляторов?

ПРИМЕЧАНИЕ. Вы должны предположить, что пространство имен / параметров / классов / функций НЕ МОЖЕТ быть сокращено в следующей реализации.

3

Решение

Вариант е ?

namespace loggingapi {
namespace attributes {
class Baz; // forward declare Baz.
}

class Biz {
typedef attributes::Baz Baz;
// C++ 11 alternative
// using Baz = attributes::Baz;

int f(Baz* b);
}
} // namespaces

Не забывайте, что псевдоним может сделать для вас …

3

Другие решения

Я бы пошел с б) вариант. Мои причины следующие:

  • Мы предполагаем, что разработчик знает, в каком пространстве имен он находится сейчас. Так что, глядя на class Bizразработчик должен знать, что этот класс находится в loggingapi пространство имен, поэтому нет необходимости явно указывать его.
  • а) вариант, с другой стороны, недостаточно ясен, потому что мы должны указать, что Baz а также Biz на самом деле в разных пространствах имен. Кроме того, это не собираюсь компилировать, потому что компилятор будет искать Baz в loggingapi пространство имен, и его там нет.
2

Вы должны выбрать (б). Это более гибкий. Если вы решили переместить или (задохнуться) вырезать и вставить f и это связывает типы с новым пространством имен или проектом, затем использование (b) гарантирует, что структура объявлений остается внутренне согласованной.

Вы можете добавлять, удалять или переименовывать внешние пространства имен переноса, не затрагивая прилагаемый код.

1

В h-файле лучше использовать полностью определенные имена, чтобы избежать возможной неоднозначности в клиентском коде. В файле .cpp вы можете использовать короткие обозначения, если вы предпочитаете это, если нет конфликта имен.

1

Если у компилятора есть некоторая двусмысленность, он обязательно сообщит об ошибке.

Я считаю, что вопрос должен быть в отношении человеческого читателя, который является довольно субъективным.
Соглашение об именах зависит от

  1. Предопределенный стиль кодирования
  2. Где вы объявляете функцию f()

Нет четкого выбора над другим. Я бы предпочел, чтобы оба объекта принадлежали одному namespace тогда я опущу хотя бы эту часть из названия:

namespace loggingapi {
namespace attributes {
class Baz; // forward declare Baz.
}

class Biz {
int f(attribute::Baz* b);
};      // ^^^^^^^^^^^^^
}
0