Frage

Here is my code. First I defined two class:

#include <iostream>

using namespace std;

template<class Datatype>
class Node
{
    public:
        Node()
        {
            next = NULL;
            prev = NULL;
        }
        Node* getNext() const
        {
            return next;
        }
        Node* getPrev() const
        {
            return prev;
        }
        Datatype* getData() const
        {
            return &data;
        }
        void changeNext()
        {
            next = NULL;
        }
        void changeNext(Node& nextNode)
        {
            next = &nextNode;
        }
        void changePrev()
        {
            prev = NULL;
        }
        void changePrev(Node& prevNode)
        {
            prev = &prevNode;
        }
        Node* addNext(Node &);
        Node* addPrev(Node &);
        void nodeDel();
        void addData(Datatype &);
    private:
        Node* next;
        Node* prev;
        Datatype data;
};

template<class Datatype>
class Stack
{
    public:
        int push(Datatype &);
        Datatype pop();
        Datatype* peek();
    private:
        Node<Datatype> node;
};

This file is called my_node.h. The defines of some functions are in the other file, called my_node.cpp. It is like this:

#include "my_node.h"

using namespace std;

template <class Datatype>
Node<Datatype>* Node<Datatype>::addNext(Node<Datatype>& new_node)
{
    if (next == NULL)
    {
        changeNext(new_node);
        new_node.changePrev(*this);
    }
    else
    {
        Node* next = getNext();
        changeNext(new_node);
        new_node.changePrev(*this);
        next -> changePrev(new_node);
        new_node.changeNext(*next);
    }
    return &new_node;
}

template <class Datatype>
Node<Datatype>* Node<Datatype>::addPrev(Node<Datatype>& new_node)
{
    if (prev == NULL)
    {
        changePrev(new_node);
        new_node.changeNext(*this);
    }
    else
    {
        Node* prev = getPrev();
        changePrev(new_node);
        new_node.changeNext(*this);
        prev -> changeNext(new_node);
        new_node.changePrev(*prev);
    }
    return &new_node;
}

template<class Datatype>
void Node<Datatype>::nodeDel()
{
    if (prev == NULL && next == NULL)
        ;
    else if (prev == NULL)
    {
        Node* next = getNext();
        next -> changePrev();
    }
    else if (next == NULL)
    {
        Node* prev = getPrev();
        prev -> changeNext();
    }
    else
    {
        Node* next = getNext();
        Node* prev = getPrev();
        next -> changePrev(*prev);
        prev -> changeNext(*next);  
    }
    delete this;
    return;
}

template <class Datatype>
void Node<Datatype>::addData(Datatype &new_data)
{
    data = new_data;
}

template <class Datatype>
int Stack<Datatype>::push(Datatype &new_data)
{
    Node<Datatype> *pt_node = new Node<Datatype>;
    if (pt_node == NULL)
        return -1;

    Datatype *pt_data;

    pt_data = (this -> node).getData();
    pt_node -> addData(*pt_data);   
    (this -> node).addData(new_data);

    pt_node -> addNext(this -> node);
}

template <class Datatype>
Datatype Stack<Datatype>::pop()
{
    Datatype temp((this -> node).data);
    Datatype* new_fir = ((this -> node).getNext()) -> getData();
    (this -> node).addData(*new_fir);
    ((this -> node).getNext())->nodeDel();
    return temp;
}

template <class Datatype>
Datatype* Stack<Datatype>::peek()
{
    return (this->node).getData();
}

So above, I declare class in .h file and define some function of those classes in .cpp file. Now, I wrote a test file to test how it works. Test file test.cpp is like this:

#include <iostream>
#include "my_node.h"

using namespace std;

int main()
{
    Stack<float> test_stack;
    float a = 2.3;
    float b = 3.4;
    test_stack.push(a);
    test_stack.push(b);

    cout << test_stack.pop();
    cout << test_stack.pop();

    return 0;   
}

The command I use is simply:

g++ -g -Wall my_node.cpp test.cpp -o test

The compiling error is like this:

/tmp/ccYaX0on.o: In function `main':
/home/user/cpp/oop_eg/test.cpp:11: undefined reference to `Stack<float>::push(float&)'
/home/user/cpp/oop_eg/test.cpp:12: undefined reference to `Stack<float>::push(float&)'
/home/user/cpp/oop_eg/test.cpp:14: undefined reference to `Stack<float>::pop()'
/home/user/cpp/oop_eg/test.cpp:15: undefined reference to `Stack<float>::pop()'
collect2: ld returned 1 exit status

I feel so strange because I defined all those functions.

Thanks, Kevin Zhou

War es hilfreich?

Lösung

With templates, you generally have to put the whole thing (declaration and definition) into a header file. That's because the code which uses the template needs to see the definition in order to instantiate it.

Basically, you can probably just cut+paste all the functions from my_node.cpp into my_node.h.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top