Danny
Danny

Reputation: 9624

C++ 3D Vector Template

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

Answers (2)

Jon Purdy
Jon Purdy

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

Dark Falcon
Dark Falcon

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

Related Questions