Правильный способ определения методов пространства имен C++.файл cpp
вероятно, дубликат, но не простой для поиска...
данный заголовок как:
namespace ns1
{
class MyClass
{
void method();
};
}
Я вижу method()
определяется несколькими способами .файл cpp:
Вариант 1:
namespace ns1
{
void MyClass::method()
{
...
}
}
Вариант 2:
using namespace ns1;
void MyClass::method()
{
...
}
Вариант 3:
void ns1::MyClass::method()
{
...
}
есть ли "правильный" способ сделать это? Есть ли среди них "неправильность" в том, что они не означают одно и то же?
8 ответов:
Версия 2 непонятно и не легко понять, потому что вы не знаете, какое пространство имен
MyClass
принадлежит и это просто нелогично (функция класса не в том же пространстве имен?)Версия 1 права, потому что она показывает, что в пространстве имен вы определяете функцию.
версия 3 является правильным также потому, что вы использовали
::
оператор разрешения области для ссылки наMyClass::method ()
в пространстве именns1
. Я предпочитаю вариант 3.посмотреть Пространства Имен (C++). Это лучший способ сделать это.
5 лет спустя, и я подумал, что упомяну об этом, что выглядит красиво и не является злом
using ns1::MyClass; void MyClass::method() { // ... }
Я использую версию 4 (ниже), потому что она сочетает в себе большинство преимуществ версии 1 (краткость резоективного определения) и версии 3 (быть максимально явным). Главным недостатком является то, что люди не привыкли к нему, но поскольку я считаю, что он технически превосходит альтернативы, я не возражаю.
версия 4: используйте полную квалификацию, используя псевдонимы пространства имен:
#include "my-header.hpp" namespace OI = outer::inner; void OI::Obj::method() { ... }
в моем мире я часто использую псевдонимы пространства имен, поскольку все явно квалифицированный - если он не может (например, имена переменных) или это известная точка настройки (например, swap() в шаблоне функции).
версия 3 делает связь между классом и пространством имен очень явной за счет большего набора текста. Версия 1 избегает этого, но захватывает связь с блоком. Версия 2 имеет тенденцию скрывать это, поэтому я бы избегал этого.
оказывается, это не только "дело стиля кодирования". Номер. 2 приводит к ошибке связывания при определении и инициализации переменной, объявленной extern в заголовочном файле. Взгляните на пример в моем вопросе. определение константы в пространстве имен в cpp-файле
все стороны правы, и каждый из них имеет свои преимущества и недостатки.
в версии 1 у вас есть преимущество в том, что вам не нужно писать пространство имен перед каждой функцией. Недостатком является то, что вы получите скучную идентификацию, особенно если у вас есть более одного уровня пространств имен.
в версии 2 Вы делаете свой код чище, но если у вас есть более одного пространства имен, реализуемого в CPP, один может получить доступ к функциям другого и переменные напрямую, что делает ваше пространство имен бесполезным (для этого файла cpp).
в версии 3 вам придется вводить больше, и ваши функциональные линии могут быть больше, чем экран, что плохо сказывается на эффектах дизайна.
есть и другой способ, которым некоторые люди используют его. Он похож на первую версию, но без проблем с идентификацией.
это так:
#define OPEN_NS1 namespace ns1 { #define CLOSE_NS1 } OPEN_NS1 void MyClass::method() { ... } CLOSE_NS1
это до вас, чтобы выбрать, какой из них лучше для каждой ситуации =]
Руководство По Стилю Googles C++ диктует свою версию 1, без отступа, хотя.
Я выбираю Num.3 (а.к.а. подробного версия). Это больше типизация, но намерение точно для вас и для компилятора. Проблема, которую вы разместили как есть, на самом деле проще, чем в реальном мире. В реальном мире существуют другие области для определений, а не только члены класса. Ваши определения не очень сложны только с классами-потому что их область никогда не открывается (в отличие от пространств имен, глобальной области и т. д.).
Num.1 это может не сработать с областями других классов - ничего это можно снова открыть. Таким образом, вы можете объявить новую функцию в пространстве имен, используя этот подход, или ваши строки могут быть заменены через ODR. Это потребуется для некоторых определений (в частности, для специализации шаблонов).
Num.2 это очень хрупко, особенно в больших кодовых базах - по мере сдвига заголовков и зависимостей ваша программа не сможет компилироваться.
Num.3 это идеально, но много, чтобы напечатать-что ваше намерение состоит в том, чтобы определить что-то. Этот делает именно это, и компилятор запускает, чтобы убедиться, что вы не ошиблись, определение не синхронизировано с его объявлением и т. д..