Undefined reference compiling with g ++

1

I usually use g ++ to compile my code, but now that I've started to learn template I can not compile for anything, the following error appears:

g++ -c pilha.cpp pilha-infinita.cpp
g++ pilha.o pilha-infinita.o -o pilha.exe

    pilha-infinita.o: na função 'main':
pilha-infinita.cpp:(.text+0x2c): referência indefinida para 'pilha<int>::vazio()'
pilha-infinita.cpp:(.text+0x3f): referência indefinida para 'pilha<int>::topo()'
pilha-infinita.cpp:(.text+0x69): referência indefinida para 'pilha<int>::~pilha()'
pilha-infinita.cpp:(.text+0x8b): referência indefinida para 'pilha<int>::~pilha()'
collect2: error: ld returned 1 exit status

Here are the codes for the stack.h, stack.cpp, and stack-infinite.cpp files below:

// stack.h

#include <iostream>
#include <stdlib.h>

using namespace std;

template <class T>
class elemento
{
    T dado;
    elemento<T> *prox;
};

template <class T>
class pilha
{
private:
    elemento<T> *top;
public:
    pilha() { top = NULL; }
    bool empilha(T);
    T topo();
    T pop();
    bool vazio();
    ~pilha();

};

// stack.cpp

#include "pilha.h"
#include <stdio.h>
#include <stdlib.h>


template <class T>
pilha<T>::~pilha()
{
    delete [] top;
}

template <class T>
bool pilha<T>::empilha(T x)
{
    if (top==NULL)
    {
        top = new elemento<T>;
        top->dado = x;
        top->prox = NULL;
        return true;
    }
    else
    {
        elemento<T> *aux = new elemento<T>;
        aux->dado = x;
        aux->prox = top;
        top = aux;
        return true;
    }
    return false;
}

template <class T>
T pilha<T>::topo()
{
    if (!vazio())
    {
        return top->dado;
    }
    return -1; //RETORNA -1 QUANDO A PILHA ESTA VAZIA
}

template <class T>
T pilha<T>::pop()
{
    if (vazio())
    {
        return -1; //RETORNA -1 QUANDO A PILHA ESTA VAZIA
    }
    else
    {
        T aux = top->dado;
        top = top->prox;
        return aux;
    }
}

template <class T>
bool pilha<T>::vazio()
{
    return (top==NULL);
}

// stack-infinite.cpp

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

using namespace std;

int main()
{
    pilha<int> p;
    if (!p.vazio())
    {
        cout<<p.topo()<< endl;
    }
    p.empilha(1);
    cout<<p.pop()<< endl;
    p.empilha(2);
    cout<<p.pop()<< endl;
    p.empilha(3);
    cout<<p.pop()<< endl;
    p.empilha(4);
    cout<<p.pop()<< endl;
    p.empilha(5);
    cout<<p.pop()<< endl;
    p.empilha(6);
    p.empilha(7);
    p.empilha(8);
    cout<<p.pop()<< endl;
    p.empilha(9);
    p.empilha(10);
    p.empilha(11);
    p.empilha(12);
    p.empilha(13);
    cout<<p.pop()<< endl;
    p.empilha(14);

    cout<<p.topo()<< endl;

    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    return 0;
}

After entering the public is giving the following errors:

pilha-infinita.o: na função 'main':
pilha-infinita.cpp:(.text+0x2c): referência indefinida para 'pilha<int>::vazio()'
pilha-infinita.cpp:(.text+0x3f): referência indefinida para 'pilha<int>::topo()'
pilha-infinita.cpp:(.text+0x69): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x75): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x9f): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0xab): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0xd5): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0xe1): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x10b): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x117): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x141): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x14d): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x177): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x188): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x199): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x1a5): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x1cf): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x1e0): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x1f1): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x202): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x213): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x21f): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x249): referência indefinida para 'pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x255): referência indefinida para 'pilha<int>::topo()'
pilha-infinita.cpp:(.text+0x27a): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x29f): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x2c4): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x2e9): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x30e): referência indefinida para 'pilha<int>::pop()'
pilha-infinita.o:pilha-infinita.cpp:(.text+0x333): mais referências indefinidas para seguir 'pilha<int>::pop()'
pilha-infinita.o: na função 'main':
pilha-infinita.cpp:(.text+0x3a7): referência indefinida para 'pilha<int>::~pilha()'
pilha-infinita.cpp:(.text+0x3c9): referência indefinida para 'pilha<int>::~pilha()'
collect2: error: ld returned 1 exit status
    
asked by anonymous 26.03.2015 / 15:06

3 answers

0

I was able to resolve the problem by modifying the include in the stack-infinite.cpp file.

Instead of:

#include "pilha.h"

I put:

#include "pilha.cpp"

I did not quite understand why, but it worked. Thanks for the help!

    
27.03.2015 / 12:22
2

Change this:

template <class T>
class elemento {
    public:
        T dado;
        elemento<T> *prox;
};

You can not access private data from the class. Remember that classes have their private members by default , unlike structs .

I believe this may be the problem or at least a problem. It's not the same process but see running on ideone . Without this change it did not compile. It is likely that the compilation failure was failing linking .

    
26.03.2015 / 15:37
1

Since this is a class template, you have to put the implementation of functions in pilha.h , so that whenever you instantiate a new object, the compiler knows how to interpret the template and creates a new specific class. That is, pilha<int> and pilha<float> are interpreted as different classes and are created separately by the compiler - > Conclusion, delete pilha.cpp and write all functions in pilha.h .

As an alternative to placing implementations in pilha.h , you can, in pilha.cpp , do what is called explicit instantiation, and paste all the templates you need at the end of the file. For example, if you need stacks for int and float you can write at the end of pilha.cpp :

...
...

template <class T>
bool pilha<T>::vazio()
{
    return (top==NULL);
}

template class pilha<int>;
template class pilha<float>;
etc...
    
26.03.2015 / 21:13