문제

C ++에서 정적 변수를 사용하면 종종 하나의 변수를 생성자로 전달하는 한 변수를 초기화하려고합니다. 다시 말해, 나는 서로 의존하는 정적 인스턴스를 만들고 싶습니다.

단일 .cpp 또는 .h 파일 내에서 이것은 문제가되지 않습니다. 인스턴스는 선언 된 순서대로 생성됩니다. 그러나 다른 컴파일 장치의 인스턴스로 정적 인스턴스를 초기화하려면 순서를 지정할 수없는 것 같습니다. 결과적으로 날씨에 따라 다른 사람에 의존하는 인스턴스가 구성되고 나중에 다른 인스턴스 만 구성 될 수 있습니다. 결과는 첫 번째 인스턴스가 잘못 초기화되었습니다.

정적 객체가 올바른 순서로 생성되도록하는 방법을 아는 사람이 있습니까? 솔루션을 오랫동안 검색하여 모든 솔루션 (Schwarz Coun

한 가지 가능성은 정적 기능 멤버의 트릭입니다.

Type& globalObject()
{
    static Type theOneAndOnlyInstance;
    return theOneAndOnlyInstance;
}

실제로 이것은 효과가 있습니다. 유감스럽게도 GlobalObject.memberFunction () 대신 globalObject (). memberfunction ()을 작성해야합니다.

업데이트: 귀하의 반응에 감사드립니다. 유감스럽게도, 내가 내 자신의 질문에 대답 한 것처럼 보입니다. 나는 그것과 함께 사는 법을 배워야 할 것 같아요 ...

도움이 되었습니까?

해결책

당신은 당신 자신의 질문에 대답했습니다. 정적 초기화 순서는 정의되지 않았으며, 그 주위의 가장 우아한 방법 (정적 초기화를 수행하는 동안 완전히 리팩토링되지 않음)은 함수의 초기화를 래핑하는 것입니다.

시작하는 C ++ FAQ 항목을 읽으십시오 https://isocpp.org/wiki/faq/ctors#static-init-order

다른 팁

아마도 많은 글로벌 정적 변수가 필요한지 여부를 재고해야 할 수도 있습니다. 때로는 유용 할 수 있지만 종종 일부 정적 변수가 다른 정적 변수에 의존한다는 것을 알면 더 작은 로컬 범위로 리팩터링하는 것이 훨씬 간단합니다.

그러나 당신은 옳습니다. 특정 초기화 순서를 보장 할 방법이 없으므로 마음이 정해져 있다면 언급 한 것처럼 기능의 초기화를 유지하는 것이 가장 간단한 방법 일 것입니다.

실제로 이것은 효과가 있습니다. 유감스럽게도 GlobalObject.memberFunction () 대신 globalObject (). memberfunction ()을 작성해야합니다.

그러나 가장 중요한 것은 그것이 작동하고 그것이 실패 증거라는 것입니다. 올바른 사용법을 우회하는 것은 쉽지 않습니다.

프로그램 정확성이 최우선 과제 여야합니다. 또한, IMHO, 위의 ()는 순전히 문체입니다 - 즉. 완전히 중요하지 않습니다.

플랫폼에 따라 너무 많은 동적 초기화에주의하십시오. 동적 초기화제를 위해 발생할 수있는 비교적 적은 양의 정리가 있습니다 (참조 여기). 회원이 다른 글로벌 객체를 포함하는 글로벌 객체 컨테이너를 사용 하여이 문제를 해결할 수 있습니다. 그러므로 당신은 다음과 같습니다.

Globals & getGlobals ()
{
  static Globals cache;
  return cache;
}

프로그램의 모든 글로벌 객체를 정리하기 위해 ~ globals ()에 대한 호출은 단 하나뿐입니다. 글로벌에 액세스하려면 여전히 다음과 같은 내용이 있습니다.

getGlobals().configuration.memberFunction ();

정말로 원한다면 매크로를 사용하여 매크로로 포장 할 수 있습니다.

#define GLOBAL(X) getGlobals().#X
GLOBAL(object).memberFunction ();

그러나 이것은 초기 솔루션에서 구문 설탕 일뿐입니다.

대부분의 컴파일러 (링커)는 실제로 순서를 지정하는 (포트 불가능한) 방법을 지원합니다. 예를 들어, Visual Studio를 사용하면 사용할 수 있습니다. init_seg Pragma는 여러 그룹으로 초기화를 주선합니다. Afaik 각 그룹 내에서 주문을 보장 할 방법이 없습니다. 이것은 포트가 없기 때문에 디자인을 요구하지 않도록 디자인을 고칠 수 있는지 고려할 수 있지만 옵션이 있습니다.

이 스레드의 나이를 가지게되면 내가 찾은 솔루션을 제안하고 싶습니다. 많은 사람들이 나에게 지적했듯이 C ++는 정적 초기화 순서를위한 메커니즘을 제공하지 않습니다. 내가 제안하는 것은 클래스의 정적 메소드 내부의 각 정적 멤버를 캡슐화하여 멤버를 초기화하고 객체 지향적 인 방식으로 액세스를 제공하는 것입니다. 다른 멤버들 중에는 "pi"를 포함하는 "Math"라는 클래스를 정의하려고한다고 가정 해 보겠습니다.

class Math {
public:
   static const float Pi() {
       static const float s_PI = 3.14f;
       return s_PI;
   }
}

S_PI는 PI () 메소드가 처음으로 호출 된 시간에 초기화됩니다 (GCC). 주의하십시오 : 정적 스토리지가있는 로컬 객체에는 구현 의존적 인 수명이 있습니다. 자세한 내용은 6.7.4 in을 확인하십시오. 2.

정적 키워드, C ++ 표준

메소드에서 정적을 감싸면 주문 문제가 해결되지만 다른 사람들이 지적했듯이 스레드 안전하지는 않지만 문제가되는 경우 스레드를 만들 수 있습니다.

// File scope static pointer is thread safe and is initialized first.
static Type * theOneAndOnlyInstance = 0;

Type& globalObject()
{
    if(theOneAndOnlyInstance == 0)
    {
         // Put mutex lock here for thread safety
         theOneAndOnlyInstance = new Type();
    }

    return *theOneAndOnlyInstance;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top