I have a mystery on my hands. I am trying to learn managed C++ coming from a C# background and have run into a snag. If I have a project which includes two classes, a base class Soup and a derived class TomatoSoup which I compile as a static library (.lib), I get unresolved tokens on the virtual methods in Soup. Here is the code:
Soup.h
namespace Abstracts
{
public ref class Soup abstract
{
public:
virtual void heat(int Degrees);
};
}
TomatoSoup.h
#include "Soup.h"
namespace Abstracts
{
public ref class TomatoSoup : Abstracts::Soup
{
public:
virtual void heat(int Degrees) override;
};
}
TomatoSoup.cpp
#include "TomatoSoup.h"
void Abstracts::TomatoSoup::heat(int Degrees)
{
System::Console::WriteLine("Soup's on.");
}
Main.cpp
#include "TomatoSoup.h"
using namespace System;
int main(array<System::String ^> ^args)
{
Abstracts::TomatoSoup^ ts = gcnew Abstracts::TomatoSoup();
return 0;
}
I get this link-time error on Main.proj:
1>Main.obj : error LNK2020: unresolved token (06000001) Abstracts.Soup::heat
I've tried setting
virtual void heat(int Degrees)=0;
I've tried implementing heat in the base class
virtual void heat(int Degrees){}
and get an unreferenced formal parameter warning treated as an error.
This issue is driving me crazy and I hope to prevent it from driving other developers nuts in the future.
UPDATE: This worked with Greg Hewgill's argument-name commenting method when the TomatoSoup::heat was implemented in the header file, but the error came back when I moved the implementation to TomatoSoup.cpp. I've modified the question to reflect that.
The error you are getting (LNK2020) means the linker can't find a definition for the Abstracts.Soup::heat
function anywhere. When you declare the function as virtual void heat(int Degrees);
the linker will expect to find the function body defined somewhere.
If you intend not to supply a function body, and require that subclasses eventually override the function, you should do as you indicated in solution 1:
virtual void heat(int Degrees) = 0;
This tells the compiler that you aren't going to implement the function. What happens when you do that?
Also, with reference to your second solution:
virtual void heat(int Degrees) {}
the compiler is telling you that you don't reference the Degrees parameter within the function. One way to avoid this warning in C++ is to not give the parameter a name:
virtual void heat(int /*Degrees*/) {}
Supplying an empty implementation is a bit different from a pure virtual (= 0
) declaration, though.