2011-10-24 3 views
2

나는 다음과 같은 코드를 가지고 : 나는 더 이상 CPP 파일에이 헤더 파일을 포함하는 경우

#ifndef GOOGLESET_PHP_H 
#define GOOGLESET_PHP_H 
zend_class_entry *googleset_ce; 
#endif /* GOOGLESET_PHP_H */ 

어떤 이유를, 컴파일러는 내가 googleset_ce 더 선언하고 있다는 소리 질러 한번 이상. 위의 조건부 매크로가이를 피하려면 충분하지 않아야합니까?

+1

당신은'GOOGLESET_PHP_H'이 * * 정의하는 방법을 우리에게 보여 주었다. 또한 사용 된 * (아마도 같은 헤더 파일에서) 사용법을 보여줄 수 있습니까? – NPE

답변

7

당신은 extern 키워드를 사용해야합니다.

이것은 글로벌 변수가 싫어하는 이유 중 하나입니다.

5

예. 컴파일 단위 당 으로 한 번만 선언됩니다.

가드를 포함하면 .cpp를 사용하는 경우에만 한 번만 선언해야합니다.

따라서 A.hB.himpl.cpp에 모두 포함되어있는 경우 A.h이 처음에만 포함됩니다.

귀하의 경우에는 포함 가드 매크로의 값을 정적 포인터 변수로 정의하고 있습니다. 따라서 impl.cpp에 한 번만 입력해도 동일한 파일을 포함하는 impl2.cpp에 해당 파일이 포함되므로 정적 변수를 사용하기를 원하면 고정 시간 변수는 링크 시간에 중복 정의가됩니다 (

) 일반적으로 나쁜 디자인 임) 함수에서 랩핑하는 것이 좋습니다. 이 변수가 진정한 글로벌 있는지 만들기 때문에

myClass* getInstance() { 
static myClass instance; 
return &instance; 
} 

이 (다윈 같은) 어떤 아키텍처 static 변수가없는 프로세스 당, 동적 라이브러리마다 고유한지가 약간 더, 그래서 혼란 행동/이동성을 주도 할 수

정적 관련 초기화는 항상 main보다 먼저 발생하므로 순서가 보장되지 않습니다./헤더는 여러 가지가 .c에 포함되어있는 경우

myClass** getGlobalRef() { 
    static myClass* val; 
    return &val; 
    } 

    //and you set it at run-time, avoiding static-initialization happening before main 
    * getGlobalRef() = new myClass(); 
+0

는 그래서 통근 선언해야하고 제대로 CPP 파일에 선언? –

+1

당신이 * *이 통근 .H와 제대로 * 그것을 .cpp 파일에 * 초기화 선언합니다. 위의 더 나은 접근법을 읽어보십시오. – lurscher

+0

이것은 작은 학습 프로젝트입니다. 어떻게 코드를 변경하여 코드가 깨지지 않습니까? –

0

: 변수가 "요구에"초기화되고, 그래서이 초기화 순서에 의해 영향을받지 않는 정적 함수를 변수로하는

글로벌 포인터를 초기화하는 문제 .cpp 파일은 실제로 여러 .obj 파일에서 선언됩니다. 네임 스페이스 또는 클래스에 캡슐화해야하므로이를 포함하는 각 .cpp 파일의 전역 변수로 간주되지 않습니다.

#ifndef GOOGLESET_PHP_H 
#define GOOGLESET_PHP_H 

extern zend_class_entry * googleset_ce; 

#endif // GOOGLESET_PHP_H 

그렇지 않으면 컴파일러는이 헤더를 포함하는 모든 파일의 변수를 선언하는 생각 :

0

lurscher가 답을 갖고 있습니다. 동일한 전역 변수를 .cpp 파일로 공유하려는 경우,이를 수행하는 한 가지 방법은 .cpp 파일 중 하나에서 전역 변수를 선언 한 다음 헤더 파일 내부에서 extern으로 선언하는 것입니다.예를 들어

:

main.cpp 
zend_class_entry *googleset_ce = NULL; 

googleset.h 
#ifndef GOOGLESET_PHP_H 
#define GOOGLESET_PHP_H 
extern zend_class_entry *googleset_ce; 
#endif /* GOOGLESET_PHP_H */ 
1

그것이 링커 에러 아니라 컴파일러 에러임을주의. 링커가 헤더 파일을 포함하여 모든 *.cpp 파일에 대해 오브젝트 파일 (*.o)을 함께 넣으려고하면 다중 정의 기호가 나타납니다.

extern 키워드를 사용하여 문제를 해결하면 기호를 고유하게 만들 수 있습니다. 그리고 그것을 하나의 다른 곳에서 선언하는 것 (그리고 오직 하나만) .cpp 파일.