정적 C ++ 클래스 멤버는 언제 초기화됩니까?
이에 대한 쉬운 대답은없는 것 같지만 정적 클래스 필드에 액세스 할 수있을 때 안전하게 만들 수있는 가정이 있습니까?
편집 : 유일한 안전한 가정은 프로그램이 시작되기 전에 모든 정적이 초기화된다는 것입니다 (를 호출하십시오 main
). 따라서 다른 정적 초기화 코드에서 정적을 참조하지 않는 한 걱정할 필요가 없습니까?
표준은 동일한 번역 단위 (일반적으로 .cpp 파일을 의미 함)에 정의 된 객체가 선언이 아닌 정의 순서대로 초기화된다는 두 가지를 보장합니다 .
3.6.2
정적 저장 기간 (basic.stc.static)이있는 객체의 저장소는 다른 초기화가 발생하기 전에 0으로 초기화되어야합니다 (dcl.init). 제로 초기화 및 상수 표현식을 사용한 초기화를 통칭하여 정적 초기화라고합니다. 다른 모든 초기화는 동적 초기화입니다. 정적 저장 기간이 상수 표현식 (expr.const)으로 초기화 된 POD 유형 (basic.types)의 객체는 동적 초기화가 발생하기 전에 초기화되어야합니다. 동일한 번역 단위의 네임 스페이스 범위에 정의되고 동적으로 초기화 된 정적 저장 기간을 가진 객체는 해당 정의가 번역 단위에 나타나는 순서대로 초기화됩니다.
다른 보장 된 점은 번역 단위의 정적 객체 초기화가이 번역 단위의 객체 또는 함수를 사용하기 전에 수행된다는 것입니다.
main의 첫 번째 명령문 이전에 네임 스페이스 범위의 객체에 대한 동적 초기화 (dcl.init, class.static, class.ctor, class.expl.init)가 수행되었는지 여부는 구현에 따라 정의됩니다. 초기화가 main의 첫 번째 문 이후 어느 시점으로 지연되면 초기화 할 객체와 동일한 번역 단위에 정의 된 함수 또는 객체를 처음 사용하기 전에 발생합니다.
내가 보장하는 다른 것은 없습니다 (특히 다른 번역 단위에 정의 된 객체의 초기화 순서가 구현 정의 됨).
편집 Suma의 의견에서 지적했듯이 main
입력 하기 전에 초기화되는 것도 보장합니다 .
프로그램이 시작되기 전에 초기화됩니다 (즉, main
입력 되기 전에 ).
단일 CPP 파일에 두 개 이상의 정의 (정적 데이터)가있는 경우 파일에 정의 된 순서대로 초기화됩니다 (파일에서 이전 / 위에 정의 된 정의가 다음 파일보다 먼저 초기화 됨). 하나는).
둘 이상의 CPP 파일에 둘 이상의 정의 (정적 데이터)가있는 경우 CPP 파일이 처리되는 순서는 정의되지 않거나 구현에 따라 다릅니다. 이것은 프로그램이 시작되기 전에 호출되는 전역 변수의 생성자가 아직 구성되지 않았을 수있는 다른 CPP 파일에 정의 된 다른 전역 변수를 참조하는 경우 문제가됩니다. 그러나 Meyers의 Effective C ++ 항목 47 ( 글로벌 객체가 사용되기 전에 초기화되었는지 확인 )은 해결 방법을 설명합니다.
헤더 파일에 정적 변수를 정의합니다 (정적이므로 링커가 불평하지 않고도 여러 인스턴스를 가질 수 있음).
해당 변수의 생성자가 필요한 모든 것을 호출하도록합니다 (특히 헤더에 선언 된 전역 싱글 톤 생성).
... 이는 일부 시스템 헤더 파일에서 사용할 수있는 기술이라고 말합니다. 예를 들어 cin
정적 변수의 생성자가 사용하기 전에 전역 변수가 초기화 되었는지 확인 합니다.
편집에서 최종 결론이 정확합니다. 그러나 문제는 클래스 자체가 정적입니다. 내 코드에 다른 전역 데이터 / 클래스 정적 멤버를 참조하지 않는 클래스 정적 멤버가 있다고 말하는 것이 더 쉽지만이 경로를 선택하면 곧 문제가 발생할 것입니다. 실제로 클래스 정적 데이터 멤버가 아니라 클래스 정적 래퍼 메서드를 사용하는 것이 유용하다고 찾은 한 가지 접근 방식입니다. 그런 다음 이러한 메서드는 자체적으로 정적 개체를 보유 할 수 있습니다. 예를 들어
TypeX* Class2::getClass1Instance()
{
static TypeX obj1;
return &obj1;
}
참고 : 이전 답변은 다음과 같습니다.
다른 보장 된 것은 번역 단위의 정적 객체 초기화가이 번역 단위의 객체 나 함수를 사용하기 전에 수행된다는 것입니다.
이것은 완전히 정확하지 않으며 표준이 여기에서 잘못 추론됩니다. 이것은 main이 입력되기 전에 번역 단위의 함수가 호출되면 참이 아닐 수 있습니다.
실행 중에 언제든지 액세스 할 수 있다고 생각합니다. 정의되지 않은 것은 정적 변수의 초기화 순서입니다.
구현 파일 (.c / cpp / cc) 파일에서 초기화 할 수 있습니다. 컴파일러가 여러 정의에 대해 불평하므로 .h로 초기화하지 마십시오.
일반적으로 main 이전에 초기화되지만 순서는 알 수 없으므로 종속성을 피하십시오. 멤버 함수 내에서 확실히 액세스 할 수 있습니다. 정적 멤버의 경우 초기화 순서를 알 수 없습니다. 멤버가 초기화되었는지 확인하는 정적 함수로 정적 멤버를 캡슐화하는 것이 좋습니다.
이 질문에 대한 완전히 사소한 대답은 아니지만 기본적으로 제어가 프로그램의 진입 점 (메인)으로 전달되기 직전에 초기화됩니다. 초기화되는 순서는 (내가 아는 한) 정의되지 않았으며 컴파일러에 따라 다를 수 있습니다.
편집 : 명확히하기 위해 추가 된 가정이 정확합니다. 주 항목 이후에만 액세스하는 한 초기화시기 / 방법에 대해 걱정할 필요가 없습니다. 그 때 초기화됩니다.
나는 프로세스의 주 스레드가 다음 5 단계를 순서대로 실행할 것이라고 생각합니다.
CRT 라이브러리 초기화
정적 초기화
main () 함수 실행
정적 단일화
CRT 라이브러리의 통합
다른 정적 초기화 코드에서 참조 정적을 원하십니까? 다음 코드가 작동 할 수 있습니다.
class A;
static auto_ptr<A> a(auto_ptr<A>(&GetStaticA()));
A &GetStaticA(void)
{
static A *a = NULL; //the static basic type variables initialized with constant experession will be initialized earlier than the other static ones
if (a == NULL)
{
a = new A();
return *a;
}
}
참고 URL : https://stackoverflow.com/questions/1421671/when-are-static-c-class-members-initialized
'development' 카테고리의 다른 글
작업 카피 란 무엇이며 Tortoise SVN에서 "전환"이 어떤 역할을합니까? (0) | 2020.12.05 |
---|---|
C ++ 정적 초기화 순서 (0) | 2020.12.05 |
NTEXT 열을 상수 값과 비교하는 올바른 방법은 무엇입니까? (0) | 2020.12.05 |
Android 작업 표시 줄의 메뉴 항목 스타일을 지정하는 방법 (0) | 2020.12.05 |
Angular.js를 통한 세션 유지 (0) | 2020.12.05 |