문제

이에 대한 쉬운 대답은 없는 것 같습니다. 그러나 언제 정적 클래스 필드에 액세스할 수 있는지에 관해 안전하게 가정할 수 있는 것이 있습니까?

편집하다:유일한 안전한 가정은 프로그램이 시작되기 전에 모든 정적 변수가 초기화된다는 것입니다( main).그렇다면 다른 정적 초기화 코드에서 정적을 참조하지 않는 한 걱정할 것이 없습니까?

도움이 되었습니까?

해결책

표준은 두 가지를 보장합니다. 동일한 변환 단위에 정의 된 개체 (일반적으로 .cpp 파일)가 정의 순서대로 초기화됩니다 ()선언이 아닙니다):

3.6.2

정적 저장 시간 (Basic.stc.static)을 갖는 객체의 저장소는 다른 초기화가 이루어지기 전에 제로 시작 (dcl.init)이어야합니다. 일정한 표현식에 의한 제로 시작 및 초기화는 종합적으로 정적 초기화라고합니다. 다른 모든 초기화는 동적 초기화입니다. 정적 저장 시간이 상수 표현식으로 초기화 된 POD 유형 (기본 형식)의 객체 (Expr.Const)는 동적 초기화가 이루어지기 전에 초기화되어야합니다. 동일한 변환 단위의 네임 스페이스 범위에 정의 된 정적 저장 시간이있는 개체는 동적으로 초기화 된 상태에서 해당 정의가 번역 장치에 나타나는 순서로 초기화되어야합니다.

다른 보장 된 것은이 번역 장치의 객체 또는 기능을 사용하기 전에 번역 장치에서 정적 객체를 초기화한다는 것입니다.

네임 스페이스 범위의 객체의 동적 초기화 (dcl.init, class.static, class.ctor, class.expl.init)가 메인의 첫 번째 명령문 전에 수행되는지 여부는 구현됩니다. 초기화가 메인의 첫 번째 명령문 후 어느 시점으로 연기되는 경우, 초기화 할 객체와 동일한 번역 장치에 정의 된 함수 또는 객체를 처음 사용하기 전에 발생합니다.

내가 보장 한 다른 것은 없습니다 (특히 다른 번역 단위로 정의 된 객체의 초기화 순서는 구현이 정의됩니다).

Suma의 의견에 지적 된대로 편집하면 이전에 초기화 된 것으로 보장됩니다. main 입력되었습니다.

다른 팁

프로그램이 시작되기 전에 초기화되었습니다 (예 : 이전 main 입력).

단일 CPP 파일에 두 개 이상의 정의 (정적 데이터)가있는 경우 파일에 정의 된 시퀀스로 초기화되었습니다 (파일의 이전/Higher가 다음에 정의 된 것이 다음에 초기화됩니다. 하나는).

둘 이상의 CPP 파일에 정적 데이터의 두 가지 이상의 정의가있는 경우 CPP 파일이 처리되는 시퀀스는 정의되지 않은/구현 별입니다. 이는 글로벌 변수의 생성자 (프로그램이 시작되기 전에 호출)가 아직 구성되지 않은 다른 CPP 파일에 정의 된 다른 글로벌 변수를 참조하는 경우 문제입니다. 그러나 Meyers의 항목 47 효과적인 C ++ (제목이 있습니다 글로벌 객체가 사용하기 전에 초기화되도록하십시오)는 작업 계약을 설명합니다 ...

  • 헤더 파일에서 정적 변수를 정의하십시오 (링커가 불만없이 여러 인스턴스를 가질 수 있도록 정적이어서)

  • 해당 변수의 생성자가 필요한 것을 호출하도록하십시오 (특히 헤더에 선언 된 글로벌 싱글 톤을 구성하십시오)

... 그것은 일부 시스템 헤더 파일에서 사용될 수있는 기술입니다. cin 정적 변수의 생성자도 사용하기 전에 글로벌 변수가 초기화됩니다.

편집의 마지막 결론이 정확합니다. 그러나 문제는 클래스 정적 자체입니다. 내 코드에는 다른 글로벌 데이터/ 클래스 정적 멤버를 언급하지 않는 클래스 정적 멤버가 있지만이 경로를 시작하면 곧 상황이 잘못 될 것입니다. 실제로 클래스 정적 데이터 멤버가 아니라 클래스 정적 래퍼 메소드가있는 것이 실제로 유용한 한 가지 방법. 이 방법은 정적 객체를 그 자체로 고정시킬 수 있습니다. 예를 들어

TypeX* Class2::getClass1Instance()
{
    static TypeX obj1;
    return &obj1;
}

참고 : 이전 답변은 다음과 같습니다.

다른 보장 된 것은이 번역 장치의 객체 또는 기능을 사용하기 전에 번역 장치에서 정적 객체를 초기화한다는 것입니다.

이것은 완전히 정확하지 않으며 표준이 여기에서 잘못 추론됩니다. 메인이 입력되기 전에 번역 장치의 함수가 호출되는 경우에도 적용되지 않을 수 있습니다.

실행 중 언제든지 액세스 할 수 있다고 생각합니다. 정의되지 않은 것은 정적 변수의 초기화 순서입니다.

구현 파일 (.C/CPP/CC) 파일에서 초기화 할 수 있습니다. 컴파일러가 여러 정의에 대해 불평하기 때문에 .H에서 초기화하지 마십시오.

일반적으로 메인 이전에 초기화되지만 순서는 알려져 있으므로 종속성을 피합니다. 회원 기능 내에서 확실히 액세스 할 수 있습니다. 정적 멤버의 경우 초기화 순서는 알려져 있지 않습니다. 정적 멤버를 정적 함수로 캡슐화하여 멤버가 초기화되었는지 확인하는 것이 좋습니다.

이 질문에 대한 아주 간단한 대답은 없지만 기본적으로 제어가 프로그램의 진입점(기본)으로 전달되기 직전에 초기화됩니다.초기화되는 순서는 (내가 아는 한) 정의되지 않았으며 컴파일러에 따라 다를 수 있습니다.

편집하다:명확히하기 위해 추가 된 가정이 정확합니다.기본 항목 이후에만 액세스하는 한 초기화 시기/방법에 대해 걱정할 필요가 없습니다.그때까지 초기화됩니다.

Proccess의 주요 스레드가 다음 5 단계를 순서대로 실행할 것이라고 생각합니다.

  1. CRT 라이브러리의 초기화

  2. 정적 초기화

  3. main () 함수 실행

  4. 정적 단위화

  5. 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;
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top