2011-04-11 4 views
2

클래스의 인스턴스 인 전역 변수가 있습니다. 이 클래스는 생성자 (directX)에 이미지를 만들었습니다.C++ 전역 변수 수명

문제는 런타임에 액세스 위반이 발생하지만 코드가 컴파일된다는 것입니다. 문제는 클래스 생성자가 winmain 함수에서 초기화가 시작되기 전에 호출된다는 것입니다.

그래서 내가 알고 싶은

  1. 사람이 문제가 발생하여 솔루션 알고있다.

  2. 글로벌 수명은 무엇입니까? 함수에서 선언 된 변수는 반환 된 후에 손실된다는 것과 컴파일러는 모든 것이 일치하는지 확인하는 코드를 살펴 봅니다. 따라서 프로토 타입 함수를 사용해야하지만 글로벌 함수는 어디에서 수행해야합니까? 방정식에 들어 가라.

+0

afaik globals는 프로그램의 전체 수명 동안 지속되어야하지만 코드가 없으면 여러분에게 해당되는 경우 말할 수 없습니다. –

+0

전역 변수가 DLL에 있습니까? – paperjam

+0

@paperjam winmain은 루프에서 게임 실행 기능을 호출하고 코드는 책에서 나왔고 초기화와 게임 코드를 분리하도록 설계되었지만 게임 실행 기능 호출간에 파괴 될 때 상황이 전역 적이어야 함을 의미합니다 . 아이디어가 있다면 더 나은 설정으로 열어 라 – Skeith

답변

4
당신은 아마 당신이 정말로 초기화 완료 후 초기화 할 수있는 세계의 한 인스턴스를 갖고 싶어 경우 singleton pattern 같은 것을보고 싶지

은 (기본적으로 이미지가 처음 건설 될 것이다 당신 그 이후에 당신이 미리 만들어진 버전을 사용할 것입니다).

winmain이 호출되기 전에 전역 변수가 (정의되지 않은 순서로) 생성됩니다. 프로그램이 종료 될 때까지 거기에 머물러 있습니다. (소멸자가 정의되지 않은 순서로 호출된다고 믿습니다.)

전역을 클래스의 인스턴스에서 다음과 같이 변경할 수 있습니다. 이 포인터는 ... 당신은 같은 거라고 :

// so 
bigGlobalImageHolder.GetImage(); 
// becomes 
bigGlobalImageHolder->GetImage(); 
+0

올바르게 기억하면 소멸자는 생성자가 호출되는 순서와 반대되는 순서로 호출됩니다. 정의되지 않은 순서로 호출되는 생성자입니다. 그리고 심지어 두 개의 전역 변수가 같은 파일에 정의되어 있으면, 먼저 정의 된 변수가 먼저 초기화되어 마지막으로 제거됩니다. – Septagram

+4

싱글 톤은 클래스를 단일 인스턴스로 제한해야하는 매우 드문 경우에만 적용 할 수 있습니다. 여기서는이 경우와 같이 들리지 않습니다. 전역 적으로 액세스 할 수있는 객체에 대한 요구 사항 만 있습니다. C++에서 싱글 톤은 자신의 문제 (특히 스레드 안전 생성 및 파괴 순서 제어)가 많아 올바르게 구현하기가 까다로운 문제가 있습니다. 나는 싱글 톤 (singletons)에 대해서는 충고 할 것이지만,'메인 (main) '에 객체를 생성하라는 당신의 제안에 +1한다. –

0

.. 그런

// global... 
MyGlobalClass *bigGlobalImageHolder; 

// Winmain 
// Perform directX setup (don't know what that is) 
// Create the image class 
bigGlobalImageHolder = new MyGlobalClass(); 


// do the rest of your stuff... I'm guessing enter some kind of event loop 

// clean up your global 
delete bigGlobalImageHolder; 
// exit your winmain (and application) 

현재 글로벌을 참조하고 어디서나 대신 포인터를 통해 참조 수를이 "정적 초기화가 발생했습니다. n 주문 대 실패 ".

다음을 확인하십시오. this 및 다음 질문.

이미 언급했듯이 Singleton 중 하나 또는 다른 종류를 구현하고 싶을 것입니다.

0
  1. 나는이 문제에 직면 해있다. class constructor에 사용 된 코드는 모두 class constructor이 시작되기 전에 초기화해야합니다. 다른 변수가 전역 변수 인 경우 해당 생성자를 먼저 호출해야한다고 가정합니다. global 변수의 생성자는 정의되지 않은 방식으로 호출되지만, 사용자가 사용할 수있는 작은 작업은 가장 낮은 종속성에서 가장 종속적 인 순서로 동일한 파일에서 종속 전역 변수를 정의하는 것입니다.
  2. 글로벌 수명은 프로그램의 수명
0

글로벌 statical 데이터의 수명은 애플리케이션의 수명입니다 동일합니다. 그러나 정상 종료시 소멸자 으로 실행됩니다.

이 문제는 초기화/제거가 발생하는 순서가 항상 결정적이지는 않으며 확실히 이식성이 없다는 것입니다.플랫폼에 따라 다르다. 런타임 링커).

상황이 공유 객체 (동적 연결)에서 최악입니다. 일부 플랫폼에서는 링커 플래그를 사용하여 공유 객체에 '우선 순위'를 지정할 수 있으므로 정적 초기화 순서에 영향을 줄 수 있습니다. 다른 플랫폼 (예 : AIX gcc, HP/UX)은 정적 절차를 'dll 초기화 루틴'으로 표시하는 특수 컴파일러 속성이 필요합니다.


요약하면 접근 자 기능을 통한 경우를 제외하고는 통계 데이터에 의존하지 마십시오. 접근 기능은 다음과 같습니다

static int _myinternalvar = 3; 
static int GetMyInternalVar() 
{ 
     return _myinternalvar; 
} 

이 방법, 당신은 기능이 실행되기 전에 정적 초기화 된 것을 확실히 알 수 있습니다. 액세서가 데이터에 액세스 할 수있는 유일한 함수이고, 범위 내에서 정적을 선언 할 수 있습니다 (캡슐화 추가).