Winrt C++ - включить использование пространств имен в файле заголовка?

Возможный дубликат:
использование пространства имен в заголовках c++

Я разработчик C# в мире WPF, но я решил делать всю свою разработку Winrt на C++.

Одна вещь, с которой я смущаюсь, - это использование (или нет) операторов using в файлах заголовков (в отличие от ввода полных имен типов).

Гораздо проще иметь операторы using в заголовочных файлах. Многие образцы Microsoft Winrt включают операторы using в заголовки, что делает код понятным и легким для чтения. Тем не менее, я просматривал образцы С++ в предварительном просмотре новой книги Джона Петцолда, и он требует, чтобы заголовки были свободны от всех операторов using.

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

Может ли кто-нибудь дать мне окончательное объяснение этой проблемы, связанной с миром Winrt (меня не интересует С++ в других средах)

Спасибо


person Dean Chalk    schedule 28.09.2012    source источник
comment
В любой среде это плохая практика, потому что она импортирует все символы в пространстве имен в каждую единицу перевода, куда вы должны включить заголовочный файл. Вместо этого просто используйте полные имена или используя объявление пространства имен в исходных файлах. .   -  person Alok Save    schedule 28.09.2012
comment
Однозначного ответа нет, за исключением того, что многие разработчики C++ считают, что код без префиксов пространств имен неясен и труден для чтения. Это вообще исключает необходимость использования пространств имен.   -  person Bo Persson    schedule 28.09.2012
comment
Я хотел бы ответить на это, потому что я думаю, что есть хороший совет, специфичный для WinRT, который не применим к предполагаемому дубликату (поскольку он касается C++ в целом). Поскольку этот вопрос закрыт, я отвечу на него здесь, в комментариях. Прошу прощения за отсутствие форматирования. Платформа среды выполнения Windows использует множество различных пространств имен. и многие из этих пространств имен имеют очень длинные имена. Можно спорить, хорошо ли это, но это так. Полные имена в вашем коде   -  person James McNellis    schedule 28.09.2012
comment
не является приемлемым вариантом (хорошо: вы можете это сделать, но ваш код будет беспорядочным). Я считаю полезным объявить заголовочный файл (скажем, namespaces.hpp), сокращающий все пространства имен. В частности, я думаю, что полезно определить namespace win { } и использовать директивы using в этом пространстве имен для переноса каждого из Windows.* пространств имен, которые я использую, в пространство имен win. Например, namespace win { using namespace Windows.UI.Xaml; using namespace Windows.UI.Xaml.Controls; }. Редко должны возникать какие-либо конфликты (я не знаю ни одного, и я полагаю, что предполагается, что типы платформ имеют   -  person James McNellis    schedule 28.09.2012
comment
уникальные простые имена даже в разных пространствах имен). Если есть конфликты, компилятор сообщит вам, и вы можете легко использовать объявления или определения типов для их разрешения. В C++/CX я также счел полезным включить все типы из Platform в это пространство имен win, так как это тоже пространства имен платформы. Вы можете сделать это и для других типов и пространств имен. Например, в своих тестовых приложениях я сокращаю длинные пространства имен, такие как cxxreflect::reflection и cxxreflect::metadata, в одно пространство имен cxr (я делаю это только в приложениях, а не в самой библиотеке, чтобы не   -  person James McNellis    schedule 28.09.2012
comment
форсирование чего-либо на других клиентах библиотеки). Зло, ужасно и неправильно использовать директивы using в заголовочном файле в глобальном пространстве имен. Но переименовывать пространства имен или агрегировать пространства имен в другом пространстве имен вполне нормально (и это хорошая идея, особенно при написании кода для WinRT, если вы хотите сохранить здравомыслие).   -  person James McNellis    schedule 28.09.2012


Ответы (1)


В C++ принято избегать пространств имен using в заголовочных файлах по нескольким причинам.

В отличие от C#, C++ не имеет красивой и аккуратной модульной системы. Все, что вы делаете в заголовке, влияет на каждый файл, содержащий его. Таким образом, если один заголовок имеет using namespace, он эффективно загрязняет не только сам файл заголовка, но и все файлы, которые его содержат. Это может привести к неожиданным конфликтам имен.

Таким образом, в C++ наиболее распространено следующее соглашение: никогда не помещайте using namespace в заголовок. В исходных файлах вы можете сделать это, если хотите, но многие люди избегают этого даже там.

Другая причина заключается в том, что это действительно может улучшить читаемость:

Если я имею в виду vector<int>, не совсем понятно, что это это. Это может быть любой векторный класс, определенный в любом из моих включенных заголовков.

Но если я напишу std::vector<int>, то я узнаю, что это заголовок стандартной библиотеки. Это говорит мне, откуда берется тип. Я думаю, что это делает код более понятным и более легким для чтения.

Конечно, есть приемы, которые вы можете использовать, чтобы сделать это более управляемым, если вы часто ссылаетесь на определенные типы или если определенные пространства имен имеют длинные и многословные имена.

Длинные имена пространств имен могут быть псевдонимами:

namespace foo = VeryLongNamespaceName; 
// now I can do foo::bar instead of VeryLongNamespaceName::bar

или отдельные имена могут быть импортированы из пространства имен:

using std::cout; 
// now I can refer to `cout` without the std prefix

Конечно, разработчики C++ не случайно склонны использовать плоские иерархии пространств имен и короткие имена пространств имен.

Почти вся стандартная библиотека C++ находится в пространстве имен std, которое немного проще вводить, чем эквивалент .NET. (std::vector<T> против System.Collections.Generic.List<T>). Короткие имена и плоская иерархия означают, что вы можете жить без операторов using namespace.

Может ли кто-нибудь дать мне окончательное объяснение этой проблемы, связанной с миром Winrt (меня не интересует С++ в других средах)

В этом контексте не существует такого понятия, как «мир WinRT». Если вы пишете код C++ в своем приложении WinRT, вам следует следовать соглашениям и рекомендациям C++. Если вы пишете код C# в своем приложении WinRT, вам следует следовать рекомендациям C# и т. д.

Нигде в рекомендациях WinRT не говорится: «Пожалуйста, игнорируйте все, что вы обычно делаете на используемом вами языке». WinRT — это API, а не язык.

Что касается того, почему образцы Microsoft делают иначе: они образцы. Их цель — проиллюстрировать конкретные концепции и дать вам отправную точку, а не научить вас писать хороший код в целом. Предполагается, что вы можете взять концепции, которые они иллюстрируют, и вписать их в свой собственный код, не копируя различные сокращения, взятые из примеров. По той же причине во многих примерах отсутствует код обработки ошибок. Это не имеет значения для целей примера, но, конечно, не имеет значения в реальном приложении.

person jalf    schedule 28.09.2012
comment
один из лучших, наиболее полных ответов, которые я читал! - person ry8806; 28.09.2012