virtual function in template inherited class - c++

I am new to templates and I have searched the web for this error but I don't know how to fix it it.
Already checked Why can templates only be implemented in the header file?
State.h
template <class entityType>
class State
{
public:
State() = default;
virtual void Enter(entityType * owner);
};
EnterMine.h
#include "State.h"
class Miner;
class EnterMine : public State<Miner>
{
public:
EnterMine() = default;
virtual void Enter(Miner *) {
};
};
and Miner.cpp is blank
and the problem appears in main.cpp
#include "EnterMine.h"
int main()
{
EnterMine a;
}
The error I get is a linking error :
LNK2001 unresolved external symbol "public: virtual void __thiscall State::Enter(class Miner *)" (?Enter#?$State#VMiner####UAEXPAVMiner###Z)

(Note: this answer was written for the original question, it has been completely rewritten after that.)
Every function that is declared and used, should be defined somewhere.
It seems that you declare EnterMine::EnterMine() but never define it. If this constructor does nothing, either omit it (it will be implicitly defined by a compiler), or mark it as = default;.
class EnterMine : public State<Miner>
{
public:
EnterMine() = default;
...
};
This also applies to the State::State() constructor.

Even though it's a singleton, you're still calling the constructor. Thus, you will still need to define the constructor.
In fact, you need to define every function you declare in your header.

Related

Unresolved external symbol in singleton

I've got code like this:
#pragma once
#include "MV/stateSystem/StateSystem.hpp"
#include "MV/config/Config.hpp"
namespace mv
{
class Initializator
{
/* ===Objects=== */
public:
protected:
private:
static Initializator *instance;
/* ===Methods=== */
public:
//Inits the program
void init();
static Initializator& getInstance();
static void createInstance();
protected:
private:
Initializator();
Initializator(Initializator const& copy) = delete; // Not Implemented
Initializator& operator=(Initializator const& copy) = delete; // Not Implemented
};
}
and .cpp
#include "Initializator.hpp"
namespace mv
{
Initializator* Initializator::instance;
void Initializator::init()
{
StateSystem::readStatesFromFile("data/states/states.txt");
}
Initializator & Initializator::getInstance()
{
if (instance == 0)
Logger::Log(constants::error::singleton::SINGLETON_NOT_INITED, Logger::STREAM::BOTH, Logger::TYPE::ERROR);
return *instance;
}
void Initializator::createInstance()
{
if (instance == 0)
instance = new Initializator();
}
}
but my compiler has got problem:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "private: __thiscall mv::Initializator::Initializator(void)" (??0Initializator#mv##AAE#XZ) referenced in function "public: static void __cdecl mv::Initializator::createInstance(void)" (?createInstance#Initializator#mv##SAXXZ)
I can't understand it because i've got other class where code is really similar and compiler hasn't got problem with it. In the past, when i've got this problem, i had to declare static members in .cpp file (for example: Initializator* Initializator::instance; ) but now it doesn't help me.
You are declaring the ctor, but not defining it
You can define it within class declaration with
Initializator() = default;
Or
Initializator(){};
Or also in the cpp with
Initializator::Initializator(){}
As the error message is saying, Initializator::createInstance() is calling the ctor, which has to be defined even if it is private
Declaring your default ctor as private prohibits the creation of an implicilty defined default ctor. Thus, you get the unresolved external symbol linker error.
To get it working, provide a valid ctor definition in your code.
Either in the .cpp file, or in the .hpp file ( by provding an in-class definition or writing ctor() = default forcing the automatic generation of a default constructor by the compiler ).

Compiler asks for interface virtual constructor?

I am trying to achieve something similar to what is explained here.
I have an Interface class defined as:
class IInterface
{
public:
virtual bool foo() = 0;
virtual void destroy() = 0;
}
And and implementation class defined as:
class MyImplementation : public IInterface
{
MyImplementation();
~MyImplementation();
virtual bool foo();
virtual void destroy() {delete this;}
private:
MyImplementation(MyImplementation const&);
void operator=(MyImplementation const&);
}
extern "C" API MyInterface* __cdecl createMyImplementation();
This works fine in Release mode using VS2010, but in Debug mode, the compiler gives me this error:
MyImplementation.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall IInterface::IInterface(void)" (__imp_??0IInterface##QAE#XZ) referenced in function "public: __thiscall MyImplementation::MyImplementation(void)" (??0MyImplementation##QAE#XZ)
What is the problem and how can I fix this ?
From my understanding, we should not have virtual constructors... (see this question).
EDIT:
Fixed typo. foo does have a body, this is a simplified version of the real code.
Explanation of the why of the destroy function:
http://www.parashift.com/c++-faq-lite/delete-this.html
http://eli.thegreenplace.net/2011/09/16/exporting-c-classes-from-a-dll
virtual void destroy() {delete this};
What are you doing? Suiciding?
Be careful!
In your case, MyImplementation::foo() needs to have a body (i.e. defined), that's why you are getting linker error
It seems to be that your problem is that you aren't including the IInterface.obj file in the link. In release mode, the compiler realizes that the ctor is vacuous and removes calls to it. But it debug mode (for single-stepping through it), the ctor has to be there. I'm guessing that you just used the .h file.

Virtual destructor in simple program causes compiler error: "unresolved external symbol" [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I have problem with my simple data base program in C++ (with inheritance and virtual func.)
I've done class hirarchy which represents the object Weapon:
#ifndef Ammu_h
#define Ammu_h
#include <string>
#include <iostream>
using namespace std;
//////////HEADER FILE//////////////
class Weapon{
protected:
string name;
char damage;
public:
virtual void show() = 0;
//virtual ~Weapon();
};
class WhiteArm: public Weapon{
protected:
double sharpness;
double defence;
};
class Axe: public WhiteArm{
public:
Axe(string str, char dmg, double shrp, double def){
name = str;
damage = dmg;
sharpness = shrp;
defence = def;
};
void show(){
cout << this->name << this->damage << this->sharpness << this->defence << endl;
};
//class Sword: public WhiteArm{...};
//class Club: public WhiteArm{...};
};
#endif
First of all im not quite sure if my implementation is proper.
My main problem is that when I add a virtual destructor, I get error: LNK2001: unresolved external symbol "public: __thiscall Weapon::~Weapon(void)"
I thought it is necessary to make the destructor virtual when the base class contains virtual methods.
Is it good to make constructors at the end of hierarchy? (like me, upper)
I will appreciate every suggestion to my code
Thanks in advance
Your virtual destructor still needs to have an implementation, even if you mean for it to be pure virtual. I usually write them using this odd-looking syntax: virtual ~Weapon() = 0 {}.
But that evidently doesn't work with some compilers (all compilers other than Microsoft's?), and rightly so (C++11 draft § 10.4/2):
[ Note: A function declaration cannot provide both a pure-specifier
and a definition —end note ] [ Example:
struct C
{
virtual void f() = 0 { }; // ill-formed
};
Instead, you can either leave out the = 0 or locate the body outside the class definition.

C++ Inheritance With No Default Constructors

So I was trying to implement a chess game. I've got the most common link error:
error LNK2019: unresolved external symbol "public: __thiscall Bishop::~Bishop(void)" (??1Bishop##QAE#XZ) referenced in function _main
So here are the two related classes:
Bishop.h (There is no "Bishop.cpp")
#pragma once
#ifndef BISHOP_H
#define BISHOP_H
#include "ChessPiece.h"
class Bishop : public ChessPiece
{
public:
Bishop(bool isWhite) : ChessPiece(isWhite) {
}
~Bishop(void);
// pure virtual functions
virtual CellLocation *listAvailableMoves(void) {
return 0;
}
virtual char getPieceType() {
return PIECE_TYPE_BISHOP;
}
};
#endif
ChessPiece.h (there is no "ChessPiece.cpp")
#ifndef CHESSPIECE_H
#define CHESSPIECE_H
#include "Globals.h"
// Abstract class for inheritence
class ChessPiece {
public:
// Constructor
ChessPiece(bool isWhite) : m_isWhite(isWhite) {
}
~ChessPiece(void);
// pure virtual functions
virtual CellLocation *listAvailableMoves(void) = 0;
virtual char getPieceType() = 0;
// ACCESSORS, MUTATORS
// isWhite member
bool isWhite(void) const{
return m_isWhite;
}
void setIsWhite(bool isWhite) {
m_isWhite = isWhite;
}
protected:
bool m_isWhite;
};
#endif
In the "Globals.h" there are few definitions of these but it's unrelated to my function.
So I what I've done in main was simply:
Bishop somePiece(true);
cout << sizeof(somePiece) << endl;
But it gave out the LNK2019 error.
Now I know that the solution should be to adding default constructors to both classes (which didn't work for some reason) but I don't want them to be initialized with default values. Hence I don't want default constructors for any of these classes.
Is there any way that I do not create default constructors and get away with it?
You are missing the definitions of ~ChessPiece(void); and ~Bishop(void);. That's what the compiler is complaining about.
Also notice that when you declare ChessPiece(bool), the default ChessPiece() constructor is not available anymore: hence you won't be able to default construct a ChessPiece.
But if you are on C++11 and for some reasons you want to delete the default constructor manually, you can use:
ChessPiece() = delete;
Your problem is about the destructor:
unresolved external symbol "public: __thiscall Bishop::~Bishop(void)"
^
// Notice the ~
You declared a destructor but didn't provide an implementation for it.

Event handler template: unresolved external

I'm currently transitioning from C# to c++ and I'm constantly hitting road blocks. I got an event handler system from a tutorial and try to adapt it to my needs, but there is an error which I can't understand:
Event:
#pragma once
class Event
{
protected:
virtual ~Event() {};
};
Event Hander:
#pragma once
#include "Event.h"
#include "TypeInfo.h"
#include "HandlerFunctionBase.h"
#include <map>
#include <typeindex>
class EventHandler
{
public:
void HandleEvent(const Event*);
template < class T, class EventT >
void RegisterEventFunc(T*, void (T::*memFn)(EventT*));
private:
typedef std::map<std::type_index, HandlerFunctionBase* > Handlers;
Handlers _handlers;
};
[...]
#include "EventHandler.h"
template < class T, class EventT >
void EventHandler::RegisterEventFunc(T* obj, void (T::*memFn)(EventT*))
{
_handlers[std::type_index(typeid(EventT))]=
new MemberFunctionHandler< T, EventT >(obj, memFn);
}
void EventHandler::HandleEvent(const Event* event)
{
Handlers::iterator it = _handlers.find(std::type_index(typeid(*event)));
if(it != _handlers.end())
{
it->second->exec(event);
}
}
HandlerFunctionBase:
#pragma once
#include "Event.h"
class HandlerFunctionBase
{
public:
virtual ~HandlerFunctionBase() {};
void exec(const Event* event) {call(event);}
private:
virtual void call(const Event*) = 0;
};
MemberFunctionHandler:
#pragma once
#include "handlerfunctionbase.h"
template < class T, class EventT >
class MemberFunctionHandler : public HandlerFunctionBase
{
public:
typedef void (T::*MemberFunc)(EventT*);
MemberFunctionHandler(T* instance, MemberFunc memFn) : _instance(instance), _function(memFn) {};
void call(const Event* event)
{
(_instance->*_function)(static_cast< EventT* >(event));
}
private:
T* _instance;
MemberFunc _function;
};
LogHandler
(My own class, first try to use the system)
#pragma once
#include "EventHandler.h"
#include "LogEvent.h"
class LogHandler
{
public:
LogHandler(EventHandler*);
~LogHandler(void);
private:
void Handle(LogEvent*);
};
#[...]
#include "LogHandler.h"
LogHandler::LogHandler(EventHandler *handler)
{
//This line causes the error
handler->RegisterEventFunc<LogHandler, LogEvent>(this, &LogHandler::Handle);
}
LogHandler::~LogHandler(void)
{
}
void LogHandler::Handle(LogEvent* e)
{
}
What I'm getting when trying to compile this:
Error 1 error LNK2019: unresolved external symbol "public: void __thiscall EventHandler::RegisterEventFunc(class LogHandler *,void (__thiscall LogHandler::*)(class LogEvent *))" (??$RegisterEventFunc#VLogHandler##VLogEvent###EventHandler##QAEXPAVLogHandler##P81#AEXPAVLogEvent###Z#Z) referenced in function "public: __thiscall LogHandler::LogHandler(class EventHandler *)" (??0LogHandler##QAE#PAVEventHandler###Z) D:\Dropbox\C++\D-Tris\D-Tris\D-Tris\LogHandler.obj D-Tris
How is RegisterEventFunc unresolved? It's clearly implemented !?
The compiler has to know the types used to instantiate the template to actually generate the code. But it also generates code for every translation unit (one .cpp file) independently. It doesn't "ignore the files".
So at the point you have the definition of EventHandler::RegisterEventFunc, it can't know with which parameters it will be instantiated, if it's used (instantiated) outside this translation unit.
In LogHandler, it knows about the template EventHandler::RegisterEventFunc (from header file), but as there's no definition, it simply assumes theres instantiation of RegisterEventFunc<LogHandler, LogEvent> elsewhere and doesn't emit any error.
When it's linked together, the linker finds out that no one actually instantiated RegisterEventFunc<LogHandler, LogEvent> so it can't link it together and emits the error you see.
What you can do about it is either:
1) move the definition of EventHandler::RegisterEventFunc to EventHandler.h. (IMHO, this is the usual solution)
2) Or force explicit instantiation in EventHandler.cpp, like
template
void EventHandler::RegisterEventFunc<LogHandler, LogEvent>
(LogHandler* obj, void (LogHandler::*memFn)(LogEvent*))
This "solution" breaks encapsulation, adds lots of dependencies and would be hell to maintain.
3) Or use exported templates. C++ supports (supported) templates the way you want to use them through the keyword export. It was supported only by Comeau and ICC (none of GCC, CLANG, MSVC ever supported this) and now it's removed from standard (In N3690, in [diff.cpp03.temp] (Annex. C.2.7, on page 1240) the standars says: A valid C++ 2003 declaration containing export is ill-formed in this International
Standard.). Don't even try it, I added it just for sake of completeness.
Some related questions that may be interesting for you:
How do I explicitly instantiate a template function?
Using export keyword with templates
Why can templates only be implemented in the header file? (this actually seems like duplicate....)
EDIT: To your other question: You can't remove const qualifier from a variable by static_cast. Casting constness away is potentially dangerous and should be avoided, but if you absolutely need it, you can do it by const_cast< EventT* >(event).