#c #forward-declaration
#c #прямое объявление
Вопрос:
Я наткнулся на это странное прямое объявление (или что-то в этом роде), где вместо обычного:
class A;
class B{
A* var;
}
Вы можете сделать
class B{
class A* var;
}
Теперь это может быть детализированный спецификатор типа, но я не уверен в этом.
Я пробовал это сам, и у меня не возникло проблем, даже мой код стал намного чище, но, боюсь, это может вызвать проблемы с областью видимости, о которых я в настоящее время не знаю.
У кого-нибудь есть представление об этом? допустимо ли это прямое замедление?
Комментарии:
1. Взгляните на разработанный спецификатор типа
Ответ №1:
Обратите внимание, что в документе говорится:
Обратите внимание, что новое имя класса также может быть введено с помощью разработанного спецификатора типа, который появляется как часть другого объявления, но только в том случае, если поиск по имени не может найти ранее объявленный класс с таким же именем.
Таким образом, если класс B
заключен в пространство имен и предыдущее прямое объявление A
не выполняется, то оно ссылается на n2::A
то, что должно быть определено.
Комментарии:
1. Нет, это не
B::A
2. @StoryTeller-UnslanderMonica Ок. Речь идет только о том, чтобы охватить пространство имен?
3. Нет, область действия блока также играет здесь роль. Если вы находитесь внутри блока в функции, это приведет к появлению локального класса.
Ответ №2:
Теперь это может быть детализированный спецификатор типа, но я не уверен в этом.
Это так. Фактически, class A;
это объявление использует сложный спецификатор класса.
но я боюсь, что это может вызвать проблемы с областью видимости, о которых я в настоящее время не знаю
Единственный момент, связанный с областью видимости, о котором вам следует знать, это то, что если при первом обращении к классу используется сложный спецификатор типа (который сам по себе не является объявлением), поведение такое же, как если бы вы ввели прямое объявление в ближайшее пространство имен или область блока. Так, например
namespace N {
class foo {
class bar {
void func(class baz*);
};
};
};
… совпадает с
namespace N {
class baz;
class foo {
class bar {
void func(baz*);
};
};
};
Ответ №3:
Да, это допустимое прямое объявление. Это называется сложным спецификатором типа.
Цитирую разработанный спецификатор типа из cppreference.
Если поиск по имени не находит ранее объявленного имени типа, детализированный спецификатор типа вводится с помощью class, struct или union (т. Е. не с помощью enum), а class-name является неквалифицированным идентификатором, тогда детализированный спецификатор типа является объявлением класса с именем класса.
Его также можно использовать для ссылки на уже объявленный класс, даже если его имя скрыто объявлением, отличным от типа.