简体   繁体   中英

Constructor linker error using template

I just started using template.

I want to create a linked list class which stores the address of Type (could be an object). Here is the layout of my project:

linkedlist.h
node.h
node.cpp
linkedlist.cpp
main.cpp

Node.h

template <class Type> struct Node
{
public:
    Node<Type>();
    Node<Type>(Type* x = 0, Node* pNext = 0);
    Type* data;
    Node* next;
};

Node.cpp

#include "node.h"

template<class Type> Node<Type>::Node()
{
    next = 0;
    data = 0;
}
template<class Type> Node<Type>::Node(Type* item, Node* ptrNext)
{
    next = ptrNext;
    data = item;
}

linkedlist.h

#include "node.h"

template <class Type> class LinkedList
{
private:
    Node<Type>* root;

public:
    LinkedList<Type>();
    ~LinkedList<Type>();
    void insert(Type*);
    void remove(Type*);
};

linkedlist.cpp

#include "linkedlist.h"

template <class Type> LinkedList<Type>::LinkedList()
{
    root = 0;
}

template <class Type> LinkedList<Type>::~LinkedList()
{
    Node* p;
    while(p = root)
    {
        root = p->next;
        delete p;
    }
}
// many more....

In main.cpp, I have the following:

int main()
{
    int *ptrA, *ptrB;
    int a = 100, b = 10;

    ptrA = &a;
    ptrB = &b;

    LinkedList<int>myList;
    myList.insert(ptrA);
    return 0;
}

and compiler threw linker errors:

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<int>::~LinkedList<int>(void)" (??1?$LinkedList@H@@QAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall LinkedList<int>::insert(int *)" (?insert@?$LinkedList@H@@QAEXPAH@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<int>::LinkedList<int>(void)" (??0?$LinkedList@H@@QAE@XZ) referenced in function _main

Attempted Solution:

I called LinkedListmyList() instead. This can resolve the linker error, but I will not be able to call any member function.

myList.insert(ptrA) will say "Error: Expression must have a class type" if I put ().

So clearly this is not working.

What's the problem? I think the whole implementation has problems....

Thanks for your time.

Move the stuff from linkedlist.cpp .. to linkedlist.h

As it's declaring a 'template for making code' the machine code doesn't actually exist until you give the compiler the type you want to use.

For example, as long as all the template code is visible to the compiler, as soon as you go: LinkedList<int>myList the compiler creates the solid real class that makes a linkedlist of ints. In your case, the compiler can't see the template code, so isn't able to generate the machine code.


in c++11 you can say 'extern template': http://en.wikipedia.org/wiki/C%2B%2B11#Extern_template

in the header file, then implement the 'int' version in your linkeList.cpp file .. and it'll be available in main.cpp when it tries to use it.

This gives the advantage of the compiler not having to generate the machine code in every .cpp file where the template is used and makes compiling faster.

It can be done in c++98 too .. but it's a bit more tricky and not 100% portable as I understand it .. easier to just generate the code everywhere. Here's a good blurb on it for gnu gcc: http://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM