Here아래에 다음 문장이 있습니다. 어느 헤더입니까? :아래 스키마는 어떻게 cin, cout, ...에 대한 정의가 하나만있을 것입니까?
는마지막으로,
<iostream>
는 여덟 표준 전역 개체 (CIN, cout을, 등)를 제공합니다. 이 작업을 올바르게 수행하기 위해이 헤더는<istream>
및<ostream>
헤더 내용을 개 제공하지만 그 밖의 것은 없습니다. 이 헤더의 내용은 이제
#include <ostream>
#include <istream>
namespace std
{
extern istream cin;
extern ostream cout;
....
// this is explained below
static ios_base::Init __foo; // not its real name
}
, 앞서 언급 한 런타임 처벌과 같이 : 자신의 코드 중 하나가 그들을 사용하기 전에 전역 개체가 초기화해야합니다; 이 표준에 의해 보장 된 입니다. 다른 전역 개체와 마찬가지로이 개체는 한 번만 초기화되고 이어야합니다. 위와 같은 방법으로 일반적으로 구조로 이루어지며 iOS_base :: Init는 중첩 클래스 인 이 이런 이유로 지정되었습니다.
어떻게 작동합니까? 헤더가 코드 앞에 포함되기 때문에 __foo 객체는 객체보다 먼저 생성됩니다. (전역 개체는 선언 된 순서로 빌드되고 은 역순으로 소멸됩니다.) 생성자가 처음 실행되면 개의 스트림 개체가 설정됩니다.
내 질문 : 나는 여러 .cpp
파일의 헤더 파일 <iostream>
을 포함 할 때, 어떻게 보장 위의 방식이 개체에 대한 한 정의가있을 것입니다 않습니다 cin
, cout
, 등 ...?
"하나의 정의"는 재미 있지 않습니다 - 이것은 (컴파일 된) 표준 라이브러리의 일부일뿐입니다. 재미있는 것은 "하나의 초기화"입니다. (나는이 기술을 [Schwartz counter]라고 부른다 (http://stackoverflow.com/q/9251763/596781). –
AFAIK,'cout','cin' 외. 객체는 헤더에서'extern'으로 선언되고, 실제 정의는 표준 lib의 파일 안에 있습니다. 이제'ios_base :: Init'는'static'으로 선언됩니다. 따라서 각 번역 단위는 자체 복사본을 가지고 있습니다. 'Init' 객체의 생성자/소멸자는 표준 스트림 객체를 초기화/파괴 할시기를 알려주는 일종의 참조 계산을합니다. 적어도 그것은 [stdlibC++가 그것을하는 것처럼 보입니다] (http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/std/iostream?view=markup). – jrok
@jrok 당신이 말한 것은 모두 나에게 분명합니다. 필자가 이해할 수없는 것은 여러 개의'.cpp' 파일에''이 포함되어있을 때'ios_base :: Init'가 전역 객체 cin, cout, ...의 다중 정의를 피하는 방법입니다. –