How to implement class derived from templated class - c++

I have solution with 2 projects inside. In first project which is builded as library I have templated class
a.h
#pragma once
#include <memory>
template<class MessageType, class HandlerType>
class A
{
std::unique_ptr<MessageType> msg;
std::unique_ptr<HandlerType> handler;
public:
A() : msg(std::make_unique<MessageType>()), handler(std::make_unique<HandlerType>()) {}
virtual ~A() {}
};
Then derived class
b.h
#include "a.h"
#include <string>
struct MyMessage
{};
struct MyHandler
{};
class B : A<MyMessage, MyHandler>
{
std::string name;
public:
B(const std::string& str);
virtual ~B();
};
and implementing it
b.cpp
#include "b.h"
B::B(const std::string& str)
{
}
B::~B()
{}
This code builded as static library (.lib). But when I try in main project to use instance of B class:
process.cpp
#include <iostream>
#include "b.h"
int main()
{
std::cout << "Hello World!\n";
B opa("yes");
}
compiler can't link it
Rebuild started...
1>------ Rebuild All started: Project: ConsoleApplication3, Configuration: Debug Win32 ------
1>b.cpp
1>ConsoleApplication3.cpp
1>Generating Code...
1>ConsoleApplication3.vcxproj -> C:\Users\user\source\repos\tmpClass\Debug\ConsoleApplication3.lib
2>------ Rebuild All started: Project: tmpClass, Configuration: Debug Win32 ------
2>process.cpp
2>process.obj : error LNK2019: unresolved external symbol "public: __thiscall B::B(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??0B##QAE#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function _main
2>process.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall B::~B(void)" (??1B##UAE#XZ) referenced in function _main
2>C:\Users\user\source\repos\tmpClass\Debug\tmpClass.exe : fatal error LNK1120: 2 unresolved externals
2>Done building project "tmpClass.vcxproj" -- FAILED.
========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========

LNK2019 means that the corresponding lib file is not added. You need to add the Lib file directory in Properties>Linker>General>Additional Library Directories and add Lib file in Properties>Linker>Input>Additional Dependencies.
Please refer to the document: Use the functionality from the static library in the app.

Related

LNK2019: Unresolved External with Collidable Game Engine system

So I am currently working on a basic game engine with a collision system. For that system I have a CollidableGroup template class which objects register themselves too. However, I am not super experienced with templates and am running into an unresolved external error.
The class is a Singleton and the problem is comming from my GetInstance() method which is being called in the register/deregister.
Here is the code:
#ifndef CollidableGroup_
#define CollidableGroup_
#include "ContainerAlias.h"
//#include "Collidable.h"
template<class CollidableType>
class CollidableGroup {
public:
static const KL::CollidableList& GetCollideableCollection() {
GetInstance().PrivateGetColliableCollection();
};
static void Register(CollidableType& collidable_) {
GetInstance().PrivateRegister(collidable_);
};
static void Deregister(CollidableType& collidable_) {
//GetInstance().PrivateDeregister(collidable_)
};
private:
CollidableGroup();
CollidableGroup<CollidableType>(const CollidableGroup<CollidableType>&) = delete;
CollidableGroup<CollidableType>& operator=(const CollidableGroup<CollidableType>&) = delete;
~CollidableGroup() {
instance = nullptr;
};
static CollidableGroup<CollidableType>* instance;
static CollidableGroup<CollidableType>& GetInstance() {
if(!instance)
{
instance = new CollidableGroup<CollidableType>;
}
return *instance;
}
void Delete() {};
KL::CollidableList mCollidableCollection;
void PrivateDeregister(CollidableType&) {};
void PrivateRegister(CollidableType& collideable_) {
mCollidableCollection.insert(mCollidableCollection.end(), &collideable_);
};
const KL::CollidableList& PrivateGetColliableCollection() {
return mCollideablCollection;
};
};
template <typename CollidableType>
CollidableGroup<CollidableType>* CollidableGroup<CollidableType>::instance = nullptr;
//template<class CollidableType>
//inline void CollidableGroup<CollidableType>::Register(CollidableType & /*collidable_*/) {
// GetInstance();// .PrivateRegister(collidable_);
//};
#endif //!CollidableGroup_
ERROR:
1>------ Build started: Project: KatanaEngine, Configuration: Debug Win32 ------
1>Tank.cpp
1>Tank.obj : error LNK2019: unresolved external symbol "private: __thiscall CollidableGroup<class Tank>::CollidableGroup<class Tank>(void)" (??0?$CollidableGroup#VTank####AAE#XZ) referenced in function "private: static class CollidableGroup<class Tank> & __cdecl CollidableGroup<class Tank>::GetInstance(void)" (?GetInstance#?$CollidableGroup#VTank####CAAAV1#XZ)
1>C:\Users\David_Desktop\Perforce\dklimavi_DESKTOP\berthiaume2018winter_gam374\student\dklimavi\Sprint_6\katanaenginerep\KatanaEngine\Debug\KatanaEngine_Debug.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "KatanaEngine.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
mostly what #drescherjm said, you declared a constructor, but the implementation isn't in your template definition, in the .h
CollidableGroup();
You should at least do something like this:
CollidableGroup() = default;
or
CollidableGroup() {};
if you implemented it in the .cpp, it won't work. You need to write the implementation in the h file when you work with template.

Unresolved external symbol c++ for inheritance and constructor

//Baseclass.h
class Baseclass {
private:
uint8_t index;
public:
Baseclass(uint8_t index);
}
//Baseclass.cpp
#include "Baseclass.h"
Baseclass::Baseclass(uint8_t index) {
index = index;
};
//Subclass.h
#include "Baseclass.h"
class Subclass : public Baseclass {
public:
Subclass();
};
//Subclass.cpp
#include "Subclass.h"
#include "Baseclass.h"
Subclass::Subclass() : Baseclass(0) {};
What am I missing? I kept getting LNK2019 Error
Severity Code Description Project File Line Suppression State
Error
LNK2019 unresolved external symbol "public: __thiscall Baseclass::Baseclass(unsigned char)" (??Baseclass##QAE#E#Z) referenced in function "public: __thiscall Subclass::Subclass(void)" (??Subclass##QAE#XZ)
It couldn't link Baseclass constructor. Are you sure there are no issues with compiling it? If you copy pasted all of the code you lack semicolon at the end of baseclass.

linker error (unresolved symbol) with template class in DLL

I get a linker error - unresolved symbol - when using a (specialized) template class from a DLL (Visual Studio 2008 compiler). I tried to use the 'explicit template instantiation' trick described also here in Stackoverflow, but it didn't work. I broke it down to a very simple reproducable example:
I have a dynamic library (DLL) 'MyTemplates.lib' with a header file 'MyTemplates.h' (and a source file 'MyTemplates.cpp' without any code which simply includes this header file) with the following content:
template <class T>
class A
{
public:
A()
{ int x = 7; }
};
template <class T>
class B : public A<T>
{
public:
B()
{}
};
// do explicit template instantiation for classes A<int> and B<int>
// macro 'MYTEMPLATES_API' is defined in the usual way as:
//#ifdef MYTEMPLATES_EXPORTS
// #define MYTEMPLATES_API __declspec( dllexport )
//#else
// #define MYTEMPLATES_API __declspec(dllimport)
//#endif
template class MYTEMPLATES_API A<int>;
template class MYTEMPLATES_API B<int>;
Now i have another dynamic library 'UserLibary' (which links against 'MyTemplates.lib') with the files 'Util.h' and Util.cpp'. The file 'Util.h' is as follows:
#include "MyTemplates.h"
class UserClass
{
public:
UserClass();
public:
A<int> bla;
B<int> blubb;
};
and the content of the file 'Util.cpp' is:
#include "Util.h"
UserClass::UserClass()
{
}
The problem is now that my library 'UserLibrary' does compile well, but it gives two linker errors as follows:
1>Util.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall B<int>::B<int>(void)" (__imp_??0?$B#H##QAE#XZ) referenced in function "public: __thiscall UserClass::UserClass(void)" (??0UserClass##QAE#XZ)
1>Util.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall A<int>::A<int>(void)" (__imp_??0?$A#H##QAE#XZ) referenced in function "public: __thiscall UserClass::UserClass(void)" (??0UserClass##QAE#XZ)
So the linker can not find the symbols for the default constructors of classes A<int> and B<int>. Why is this possible, and how can i get rid of these linker errors ? I thought that the explict template instantiation of the class A<int> and B<int> (in file 'MyTemplates.h') would solve this, but unfortunately it doesn't seem to help - or am I using it in the wrong way ? My compiler is Visual Studio 2008, operating system is windows 7 64 bit, and code is compiled in 64bit.

"unresolved external symbol" error

Please have a look at the following code
Main.cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
system("pause");
return 0;
}
Magic.h
#pragma once
class Magic
{
public:
Magic();
~Magic();
virtual void display()=0;
};
Spell.h
#pragma once
#include "Magic.h"
#include <iostream>
#include <string>
using namespace std;
class Spell :
public Magic
{
public:
Spell(void);
Spell(string words);
~Spell(void);
void display();
private:
string words;
};
Spell.cpp
#include "Spell.h"
#include "Magic.h"
#include <iostream>
#include <string>
using namespace std;
Spell::Spell(void)
{
}
Spell::Spell(string words)
{
this->words = words;
}
Spell::~Spell(void)
{
cout << "Delete Spell" << endl;
}
void Spell::display()
{
cout << "Spell Words: " << words << endl;
}
Here, I am getting the error
1>------ Build started: Project: Revision1_1, Configuration: Debug Win32 ------
1>Spell.obj : error LNK2019: unresolved external symbol "public: __thiscall Magic::~Magic(void)" (??1Magic##QAE#XZ) referenced in function __unwindfunclet$??0Spell##QAE#XZ$0
1>Spell.obj : error LNK2019: unresolved external symbol "public: __thiscall Magic::Magic(void)" (??0Magic##QAE#XZ) referenced in function "public: __thiscall Spell::Spell(void)" (??0Spell##QAE#XZ)
1>C:\Users\yohan\Documents\Visual Studio 2010\Projects\Revision1_1\Debug\Revision1_1.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I do not understand what to do here. Why is this happening? Please help! I am new to C++ anyway..
Magic is not implementing its constructor and destructor (which also should be virtual).
Don't even declare the constructor if not necessary, e.g.
class Magic {
public:
virtual ~Magic() {}
virtual void display() = 0;
};
Unrelated: I didn't know you can display magic.
You didn't implement
Magic();
~Magic();
You'll need to either implement them inline, in an implementation file, or mark them = default.
You have declared a destructor in your Magic class but did not define it. That's why the linker complains (and the compiler doesn't).
You don't have an implementation for Magic. If your intention is for Magic to be an abstract base class, then just change its declaration to:
#pragma once
class Magic
{
public:
virtual void display()=0;
};
Remember, any method that is not followed by = 0 in the interface must be implemented in the class.

c++ visual studio 2008 issue with two projects in one solution

I have a solution created using visual studio 2008 named, "Solution", and i have two projects in that solution, project "A" and project "B". when i do a thing like below it shows fatal errors in the bottom. I have given in project A->properties->Additional include Directries as ../B
project B
B.h
#include <iostream>
using namespace std;
class B
{
public:
B();
~B();
};
B.cpp
#include "B.h"
B::B()
{
}
B::~B()
{
}
project A
A.h
#include <iostream>
using namespace std;
class A
{
public:
A();
~A();
};
A.cpp
#include "A.h"
#include "B.h"
A::A()
{
B b;
}
A::~A()
{
}
Main.cpp in project A
#include "B.h"
int main()
{
B b;
system("pause");
}
when i run it says
Error 3 fatal error LNK1120: 2 unresolved externals H:\Sol\Debug\A.exe
Error 2 error LNK2001: unresolved external symbol "public: __thiscall B::B(void)" (??0B##QAE#XZ) A.obj
Error 1 error LNK2001: unresolved external symbol "public: __thiscall B::~B(void)" (??1B##QAE#XZ) A.obj
It doesn't look like you are exporting class B out of project B. So project A sees the declaration of class B but can't find its implementation. What does project B build?