Форвардные определения и пространство имен с использованием

Меня интересует значение следующих строк кода в файле header...

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

using mynamespace::myclass;

а затем предварительное объявление того же класса:

namespace mynamespace
{
    class myclass;
}

и, наконец, предварительное объявление другого класса:

class myclass2;

Каковы тонкие различия для программиста при «использовании» и при «упреждающем объявлении»? Что предпочтительнее при написании файла header?


person Ferenc Deak    schedule 16.09.2013    source источник
comment
Эти строки не могут отображаться в том порядке, в котором вы их перечислили здесь — полное имя должно ссылаться на ранее объявленный объект.   -  person jrok    schedule 16.09.2013
comment
Различия не тонкие. using и предварительное объявление - это две разные вещи.   -  person Karthik T    schedule 16.09.2013


Ответы (3)


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

namespace N { class C; } // OK, now we know that N::C exists

using N::C;              // OK, now we can type C whenever we mean N::C

Упреждающая декларация вводит имя, декларация использования вводит аббревиатуру этого имени (т. е. вы можете опустить квалификацию пространства имен).

Неформальная аналогия с именами и фамилиями: человека сначала представят, а уже потом попадут по имени.

В качестве рекомендации: никогда не помещайте объявления использования в глобальную область видимости внутри заголовочных файлов. Это введет стенографию в каждую единицу перевода, которая включает этот заголовок, и, вероятно, приведет к конфликтам имен.

person TemplateRex    schedule 16.09.2013
comment
Что касается вашего руководства, я бы добавил в глобальном масштабе. Совершенно нормально перетаскивать имена из одного пространства имен в другое. - person Angew is no longer proud of SO; 16.09.2013

Чтобы объявить класс вперед, вам не нужна директива using, обычно лучше просто использовать полное имя в заголовке:

namespace mynamespace
{
    class myclass;
}

class A{
    mynamespace::myclass* ptr;

};

Кроме того, как отмечено jrok, вы не можете использовать using, чтобы перевести символ в текущую область до фактического (вперед) объявление символа.

person Nemanja Boric    schedule 16.09.2013

Единственное, что делает using, — это делает указанный символ доступным в текущей области. Это не связано с предварительными объявлениями.

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

namespace mynamespace {
    class myclass;
}

namespace this_header_namespace {
    using mynamespace::myclass;
}
person orlp    schedule 16.09.2013