2008-10-21 2 views
80

Я использую декларацию 'using' в C++ для добавления std :: string и std :: vector в локальное пространство имен (чтобы сохранить ввод ненужных 'std ::' s).Какова область применения «использования» в C++?

using std::string; 
using std::vector; 

class Foo { /*...*/ }; 

Какова область применения этой декларации? Если я сделаю это в заголовке, будет ли он вводить эти объявления «использования» в каждый файл cpp, который включает заголовок?

+17

На всякий случай неясно, из других ответов здесь: - ** Не помещайте декларацию `using` (или` use` директиву) в область файла в include-файле/заголовке! ** Это будет вызывают головные боли для пользователей заголовка. – 2008-10-21 19:07:07

+0

На самом деле, не помещайте декларацию `use` (директива fortiori *) в заголовок ** вообще **, * даже внутри пространства имен! * См. [Область использования объявления в пространстве имен] (http://stackoverflow.com/q/6175705/2025416). – 2016-05-22 15:07:04

ответ

53

Когда вы # включаете заголовочный файл в C++, он помещает все содержимое файла заголовка в то место, которое вы включили в исходный файл. Таким образом, включение файла с объявлением using имеет тот же эффект, что и размещение объявления using в начале каждого файла, который включает этот файл заголовка.

+43

... обычно плохой. – Catskul 2011-02-16 05:25:13

+13

Но если вы помещаете декларацию `using` внутри пространства имен, она ограничена областью этого пространства имен, как правило, это нормально (с обычными оговорками в соответствии с вашими конкретными потребностями и стилем). – Zero 2012-12-04 23:09:39

+1

... но если вы используете внутри пространства имен, убедитесь, что вы не делаете этого, чтобы попытаться обойти что-то, что обычно является плохой идеей, например, вы не можете помещать методы класса, объявленные вне пространства имен Y внутри другое пространство имен X, так что вы можете локально использовать пространство имен X. Вот почему мы в первую очередь используем namespace :: resolvers. Если это большая проблема печати, либо макрос (который может легко привести к запахам кода), либо еще лучше, изолируйте его в своем собственном источнике .cpp, где вы будете использовать только пространство имен. – osirisgothra 2014-01-17 17:29:14

5

В приведенном случае файл («единица перевода»), что означает «да», каждый файл, который его включает.

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

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

+0

Обратите внимание, что декларация `use` в классе не ведет себя так же, как и вне класса, - например, вы не можете использовать ее, вместо класса` std :: cout` вместо `std :: cout` в класс. – Zero 2012-12-04 23:07:32

2

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

86

Нет ничего особенного в заголовочных файлах, которые сохраняли бы объявление using. Это простая замена текста до начала компиляции.

Вы можете ограничить using декларацию в сфере:

void myFunction() 
{ 
    using namespace std; // only applies to the function's scope 
    vector<int> myVector; 
} 
+8

Я никогда не думал, что смогу использовать его внутри функции! – Agostino 2015-03-04 22:50:35

4

Область является то, что сфера от употребления декларации в

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

Итак, общий совет: избегать использования деклараций в глобальной области заголовков файлов.

44

Объем помощи заявления зависит от того, где он находится в коде:

  • Размещенные в верхней части файла, он имеет объем в течение всего этого файла.
  • Если это файл заголовка, он будет иметь область видимости во всех файлах, содержащих этот заголовок. В общем, это «не является хорошей идеей», как это может иметь неожиданные побочные эффекты
  • В противном случае оператор с помощью имеет объем в пределах блока, который содержит его с точки это происходит до конца блока. Если он помещен внутри метода, он будет иметь область действия внутри этого метода. Если он помещен в определение класса, он будет иметь область видимости внутри этого класса.
1

Есть несколько замечаний, которые являются довольно неквалифицированными, когда они говорят «Не делайте этого».Это слишком строго, но вы должны понимать, когда все в порядке.

Письмо using std::string никогда не будет в порядке. Написание using ImplementationDetail::Foo в вашем собственном заголовке, когда этот заголовок объявляет, что реализацияDetail :: Foo может быть в порядке, moreso, если объявление использования происходит в вашем пространстве имен. Например.

namespace MyNS { 
    namespace ImplementationDetail { 
     int Foo; 
    } 
    using ImplementationDetail::Foo; 
} 
Смежные вопросы