2010-04-15 2 views
9

для использования cout, мне нужно указать как:включают и использование пространств имен в C++

#include<iostream> 

и

using namespace std; 

Где cout определяется? в iostream, правильно? Итак, именно iostream есть в пространстве имен std?

В чем смысл обоих утверждений относительно использования cout?

Я смущен, почему мы должны включить их обоих.

+5

@Neil Тогда в чем же цель SO? Чтобы задавать вопросы, на которые не было ответа, читали книгу или искали в Интернете? –

+1

@Neil Butterworth: ладно! не более глупых вопросов после этого, не читая понятия из книги. – Moeb

+6

@ Kevin Любой, кто думает, что может изучать C++, задавая вопросы о SO, вводит в заблуждение себя и тратит наше время. – 2010-04-15 18:59:54

ответ

9

iostream - это имя файла, в котором определяется cout. С другой стороны, std - пространство имен, эквивалентное (в некотором смысле) пакету java.

cout - это экземпляр, определенный в файле iostream, внутри пространства имен std.

В другом пространстве имен может существовать другой экземпляр cout. Поэтому, чтобы указать, что вы хотите использовать экземпляр cout из пространства имен std, вы должны написать

std::cout с указанием области действия.

std::cout<<"Hello world"<<std::endl; 

Чтобы избежать std:: везде, вы можете использовать пункт using.

cout<<"Hello world"<<endl; 

Это две разные вещи. Один указывает область действия, другой - фактическое включение cout.

В ответ на ваш комментарий

Представьте себе, что в iostream два экземпляра с именем cout существуют в разных пространствах имен

namespace std{ 
    ostream cout; 
} 
namespace other{ 
    float cout;//instance of another type. 
} 

После включения <iostream>, вам все равно нужно указать пространство имен. Оператор #include не говорит «Эй, используйте cout в std ::». То, что using, для уточнения области применения

+1

@Tom: Когда я уже включил файл ('iostream'), я указал, какое определение' cout' использовать. Теперь компилятор знает, какую защиту использовать. Итак, в чем же проблема. Я все еще смущен, почему мне нужно сказать, что оно находится в пространстве имен 'std'. Это должно было быть необходимо, если была какая-то путаница. Здесь нет путаницы, так как существует только одна защита 'cout'. – Moeb

+0

См. Мой обновленный ответ – Tom

+0

@cambr: Нет, вы указали определение 'cout' для использования. Нет причин, по которым вы не могли бы определить «int cout» после этого, хотя это не очень хорошая идея. Возможно, стандарт C++ мог потребовать, чтобы пространства имен игнорировались, если есть только одно пространство имен с заданным символом, но это не так, и я не могу думать о языке, использующем пространства имен, где он работает. –

1

cout логически определен в пределах iostream. По логике, я имею в виду, что это действительно может быть в файле iostream или может быть в каком-то файле, включенном в iostream. В любом случае, включая iostream, это правильный способ получить определение cout.

Все символы в iostream находятся в пространстве имен std. Чтобы использовать символ cout, вы должны сообщить компилятору, как его найти (т. Е. Какое пространство имен). У вас есть несколько вариантов:

// explicit 
std::cout << std::endl; 

// import one symbol into your namespace (other symbols must still be explicit) 
using std::cout; 
cout << std::endl; 

// import the entire namespace 
using namespace std; 
cout << endl; 

// shorten the namespace (not that interesting for standard, but can be useful 
// for long namespace names) 
namespace s = std; 
s::cout << s::endl; 
0

В #include <iostream> референции заголовочный файл, который определяет COUT. Если вы собираетесь использовать cout, вам всегда понадобится включить.

Вам не нужно using namespace std;. Это просто позволяет использовать стенографию cout и endl и т. Д., А не std::cout и std::endl, где пространство имен является явным. Лично я предпочитаю не использовать using namespace ..., поскольку он требует, чтобы я был явным в своем смысле, хотя он, по общему признанию, более подробный.

+1

Компромисс: 'using std :: cout; используя std :: endl; ', после чего вы можете использовать' cout' и 'endl' без квалификации, не принося все пространство имен' std' в глобальное пространство имен. –

2

Если C++ реализация использует файлы заголовков в стиле C (многие из них), то есть файл, который содержит нечто похожее на:

#include ... // bunches of other things included 

namespace std { 

... // various things 

extern istream cin; 
extern ostream cout; 
extern ostream cerr; 

... // various other things 

} 

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

Говоря

using namespace std; 

вы сообщаете компилятору, что вы хотите, чтобы искать в патезрасе в дополнение к глобальному пространству имен при поиске имен. Если компилятор видит исходную строку:

return foo(); 

где-то после using namespace std; линии он будет искать foo в различных различных пространствах имен (по аналогии с областями) до тех пор, пока не найдет Foo, который отвечает требованиям этой линии. Он ищет пространства имен в определенном порядке. Сначала он выглядит в локальной области (которая на самом деле является неназванным пространством имен), а затем следующей самой локальной областью до тех пор, пока она не останется за пределами функции, а затем в названных вещах объекта-объекта (в данном случае методы), а затем в глобальные имена (функции, в этом случае, если вы не были глупыми и перегруженными(), которые я игнорирую), а затем в пространстве имен std, если вы использовали строку using namespace std;. У меня могут быть два последних неправильных порядка (std можно искать до глобального), но вы должны избегать написания кода, который зависит от этого.