Update 2: Found the forward declare bug that caused this
Update: Compiled using Visual Studio 2010 stock compiler, with c++0x enabled.
I have a class with a member function which is behaving strangely.
When I define the method in the cpp file the linker falls over with an "unresolved external symbol" error. When I move the definition to the header it compiles fine.
1) This is not a templated method 2) The cpp file is definitely being compiled 3) I'm stumped
Any thoughts?
header file
// 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 file
void TollingPathAttributesOutput::foo() {}
void TollingPathAttributesOutput::AddPathAttributes(boost::shared_ptr<TollingPathAttributes> attributes)
{
queuing_mutex::scoped_lock lock(m_dataMutex);
m_data.push_back(attributes);
}
invoking call
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
link error
1>OtCustomZenith_logic.lib(TollingPathAttributesRecorder.obj) : error LNK2019: unresolved external symbol "public: void __thiscall TollingPathAttributesOutput::AddPathAttributes(class boost::shared_ptr<class TollingPathAttributes>)" (?AddPathAttributes@TollingPathAttributesOutput@@QAEXV?$shared_ptr@VTollingPathAttributes@@@boost@@@Z) referenced in function "public: virtual void __thiscall TollingPathAttributesRecorder::Record(class TolledPath &,class boost::shared_ptr<class Path>,int)" (?Record@TollingPathAttributesRecorder@@UAEXAAVTolledPath@@V?$shared_ptr@VPath@@@boost@@H@Z)
1>..\..\..\OT\OtCustomZenith_test.exe : fatal error LNK1120: 1 unresolved externals
Thanks to every one who tried to help - unfortunately this error was about 1 foot behind the keyboard. The problem here came down to the use of forward declarations to speed up my compile time. Because I wrongly forward declared the type of TollingPathAttributes as a class instead of a struct.
This meant that the definition of the header was slightly different from the definition in the cpp as I actually included the full definition of TollingPathAttributes in the cpp file. The big thing that confused this issue was that the error messages I received were not what I was expecting to receive - as @MarkRansom says, normally if there is a mismatch between the cpp and header it will be a compile error not a link error so I have to conclude that:
1) the compiler has simply pushed ahead with the incorrect 'class' (rather than 'struct') based definition even though it knows better once it has the full definition available to it. Leading to a lib file that has a signature that is almost but not quite what the linker is looking for.
2) Some other weirdness