Reputation: 9624
I'm trying to create a Vector class using templates to store 3D positions of an object. I have created the class, but I am keep getting a error LNK2019: unresolved external symbol "public: __thiscall Vector3::~Vector3(void)" (??1?$Vector3@H@@QAE@XZ) referenced in function _main
It is something to do with me creating the Vector in the main function, but I can't figure out what is wrong with it... Here's my code:
//Vector3.h
template <typename T>
class Vector3
{
public:
Vector3(T elemOne, T elemTwo, T elemThree);
~Vector3();
void display();
protected:
T x;
T y;
T z;
};
//Vector3.cpp Constructor.
#include"Vector3.h"
template<typename T>
Vector3<T>::Vector3(T elemOne, T elemTwo, T elemThree)
{
x = elemOne;
y = elemTwo;
z = elemThree;
}
template<typename T>
Vector3<T>::~Vector3()
{
}
template<typename T>
void Vector3<T>::display()
{
cout << "X: " << x << endl;
cout << "Y: " << y << endl;
cout << "Z: " << z << endl;
}
//MainFrame.cpp
int main()
{
Vector3<int> vec(10, 20, 30);
cout << "Press any key to continue..." << endl;
return 0;
}
Any help on finding out this problem will be greatly appreciated. Thanks
Upvotes: 2
Views: 2551
Reputation: 54979
Short answer: you don’t want to include the definitions of your Vector
member functions in Vector.cpp
, and should move them to Vector.h
. The long answer is that a template is not a class: it is a template by which a class is constructed. Thus the definitions of the template must be available in the compilation unit (source file) that includes Vector.h
.
A common solution if you want to keep things separate is to make, say, VectorImpl.h
:
// VectorImpl.h
template<class T>
Vector<T>::Vector(T x, T y, T z) { ... }
And include it from Vector.h
, like so:
// Vector.h
#ifndef VECTOR_H
#define VECTOR_H
template<class T>
class Vector { ... };
#include "VectorImpl.h"
#endif
There are circumstances in which you would want to have a Vector.cpp
: in particular, if you wanted to restrict Vector
to just a few types, you would instantiate Vector
with those types explicitly in Vector.cpp
:
template class Vector<double>;
This allows you to create, for example, libraries of precompiled templates. However, for your purposes, you can just stick to the usual header-only solution.
Upvotes: 2
Reputation: 44181
Templates need to be defined in the same compilation unit in which they are used. You cannot place the implementation of a template in a different file as you have shown in your code.
I will also note that as it stands now, you don't need a destructor. You're not doing anything in it and it is not virtual, so it may be omitted to allow the compiler to generate one for you.
Upvotes: 7