2012-04-12 5 views
2

은 업데이트 2하지 않을 때 때의 C +로, 비주얼 스튜디오 2010 재고 컴파일러를 사용하여 컴파일 된 해결되지 않은 외부 방법은 CPP 파일에 정의되어 있지만 헤더에

업데이트의 원인이 전방 선언 버그 발견 + 0x가 사용 설정되었습니다.

이상하게 행동하는 멤버 함수가있는 클래스가 있습니다.

cpp 파일에서 메서드를 정의 할 때 링커가 "확인되지 않은 외부 기호"오류로 넘어집니다. 정의를 헤더로 옮기면 잘 컴파일됩니다.

1) 내가

어떤 생각을 난처한 상황에 빠진거야)에 CPP 파일이 확실히) (3) 컴파일되고있는 템플릿 방법 이 아닌가요?

헤더 파일

// THIS IS THE ERROR HERE: I forward declare TPA as a class, when it is actually a struct 
class TollingPathAttributes; // forward declare the TollingPathAttributes struct as a class (doh!) 

class TollingPathAttributesOutput 
{ 
public: 
    TollingPathAttributesOutput(HighwayCommand* command); 
    ~TollingPathAttributesOutput(); 

    void foo(); 
    void AddPathAttributes(boost::shared_ptr<TollingPathAttributes> attributes); 

protected: 
    string          m_outputFilename; 
    vector<shared_ptr<TollingPathAttributes>> m_data; 
    queuing_mutex        m_dataMutex; 
}; 

CPP 파일

void TollingPathAttributesOutput::foo() {} 

void TollingPathAttributesOutput::AddPathAttributes(boost::shared_ptr<TollingPathAttributes> attributes) 
{ 
    queuing_mutex::scoped_lock lock(m_dataMutex); 
    m_data.push_back(attributes); 
} 

호출 전화

m_output->foo(); // compiles and links no problem 
boost::shared_ptr<TollingPathAttributes> attr = 
    boost::make_shared<TollingPathAttributes>(origin, dest, UNTOLLED_OPTION, vector<int>(), 0.0, 0.0); 
m_output->AddPathAttributes(attr); // compiles fine, but only links correctly if I move the definition to the header 

링크 오류

1>OtCustomZenith_logic.lib(TollingPathAttributesRecorder.obj) : error LNK2019: unresolved external symbol "public: void __thiscall TollingPathAttributesOutput::AddPathAttributes(class boost::shared_ptr<class TollingPathAttributes>)" ([email protected]@@[email protected]@@@[email protected]@@Z) referenced in function "public: virtual void __thiscall TollingPathAttributesRecorder::Record(class TolledPath &,class boost::shared_ptr<class Path>,int)" ([email protected]@@[email protected]@[email protected]@@@[email protected]@[email protected])  
1>..\..\..\OT\OtCustomZenith_test.exe : fatal error LNK1120: 1 unresolved externals 
+4

어떻게 컴파일하나요? –

+0

내 일반 개발자는 아니므로, 기계 그래서 내가 테스트 할 수 없으며 이것은 단지 오타 일지 모르지만 m_data는 shared_ptr (네임 스페이스로 부스트하지 않음)의 벡터입니다. 다른 참조는 네임 스페이스를 갖고있는 반면 문제가 될 수 있습니까? – tmpearce

+0

@tmpearce 명백한 boost :: shared_ptr은 메소드의 호출 사이트/헤더/cpp 정의 사이의 불일치를 배제하는 것이 었습니다.일반적으로 나는 어딘가에 boost :: shared_ptr을 사용한다. 나는 shared_ptr이 boost 네임 스페이스에서 나온다고 확신한다. –

답변

3

도움을 청한 모든 분들께서 - 불행히도이 오류는 키보드 뒤에 약 1 피트 정도있었습니다. 문제는 컴파일 시간을 앞당기 기 위해 forward 선언을 사용하는 것입니다. 왜냐하면 내가 틀리게 forward는 TollingPathAttributes의 형식을 구조체 대신 클래스로 선언했기 때문입니다.

이것은 헤더의 정의가 cpp 파일의 TollingPathAttributes의 전체 정의를 실제로 포함했기 때문에 cpp의 정의와 약간 다릅니다. 이 문제를 혼란스럽게 만든 큰 이유는 내가받은 오류 메시지가 내가 기대했던 것이 아니었다는 것입니다. @MarkRansom이 말하기를 일반적으로 cpp와 헤더가 일치하지 않으면 링크 오류가 아닌 컴파일 오류가 발생합니다 나는 결론을 내려야 만한다 :

1) 컴파일러는 일단 'struct'기반의 정의보다는 잘못된 'class'를 먼저 푸시했다. 링커가 찾고있는 것과 거의 비슷하지만 서명이있는 lib 파일로 연결됩니다.

2) 다른 이상한 점

0

오류 메시지로 판단하여 .cpp 파일이 .lib로 컴파일되고 있습니다. .lib의 복사본이 두 개있을 가능성이 있습니까? 하나는 각 컴파일로 업데이트되고 다른 하나는 .exe에 링크되어 있습니까?

+0

사각 발상에서 벗어나 줘서 고맙지 만, 그렇다고 생각하지 않습니다. 나는 ** foo ** 메소드를 추가했다. **이 문제는 그 머리를 사육하고 cpp 파일의 정의만을 제공했다. (같은 메소드에서 다른 메소드를 정의하려고 시도하고있다.) 잘 작동했다. 하나의 lib 파일이지만 메서드 정의가 포함되지 않았거나 이상한 시그니처에 포함되어있을 수 있습니다. 아마도 lib 파일을 따로 떼어 놓아야 거기에있는 파일을 볼 수 있습니다. –

+0

@JamieCook, 한번해볼만한 가치가있었습니다. 같은 .cpp에서 두 개의 다른 기능이 어떻게 다른 결과를 초래할 수 있는지 이해할 수 없습니다. 서명이 헤더에있는 것과 일치하지 않더라도 컴파일러는 링커에 도착하기 전에 그것에 대해 불평해야합니다. –

+0

정확히 내가 생각한 것입니다. 따라서이 문제에 대해 너무 불쾌한 이유는 그것을 "미해결 신비"로 표시해야 할 수도 있습니다. :) –