c++ - G++ Linker error: undefined reference to -
this question has answer here:
i'm trying compile program in c++, compiler returning error:
operadoraarquivos.o: in function `split(std::string, int&)': operadoraarquivos.cpp:(.text+0x0): multiple definition of `split(std::string, int&)' main.o:main.cpp:(.text+0x0): first defined here hash.o: in function `hashtable::hashtable(int)': hash.cpp:(.text+0x65): undefined reference `lista<palavra>::lista()' hash.cpp:(.text+0xba): undefined reference `lista<palavra>::~lista()' hash.o: in function `hashtable::~hashtable()': hash.cpp:(.text+0x134): undefined reference `lista<palavra>::~lista()' hash.o: in function `hashtable::inserir(std::string, int)': hash.cpp:(.text+0x2d0): undefined reference `lista<palavra>::vazia()' hash.cpp:(.text+0x31b): undefined reference `lista<palavra>::buscar(palavra)' hash.cpp:(.text+0x34d): undefined reference `lista<int>::lista()' hash.cpp:(.text+0x365): undefined reference `lista<int>::inserir(int)' hash.cpp:(.text+0x3a5): undefined reference `lista<palavra>::inserir(palavra)' hash.cpp:(.text+0x3ce): undefined reference `lista<int>::inserir(int)' hash.cpp:(.text+0x3e7): undefined reference `lista<int>::lista()' hash.cpp:(.text+0x3ff): undefined reference `lista<int>::inserir(int)' hash.cpp:(.text+0x43f): undefined reference `lista<palavra>::inserir(palavra)' hash.o: in function `hashtable::buscar(std::string)': hash.cpp:(.text+0x590): undefined reference `lista<palavra>::buscar(palavra)' hash.o: in function `hashtable::imprimir(std::string)': hash.cpp:(.text+0x6d5): undefined reference `lista<int>::imprimir()' collect2: error: ld returned 1 exit status*****
command: g++ -o busca main.o operadoraarquivos.o lista.o hash.o
how can fix error? thankyou
main.cpp
#include "operadoraarquivos.hpp" int main(int argc, char* argv[]) { operadoraarquivos oparq(argv[1], argv[2], argv[3]); oparq.imprimirbusca(); oparq.~operadoraarquivos(); }
operadoraarquivos.cpp
#include "operadoraarquivos.hpp" operadoraarquivos::operadoraarquivos(string livro, string sw, string buscas) { this->livro.open(livro.c_str(), ios_base::in); this->sw.open(sw.c_str(), ios_base::in); this->buscas.open(buscas.c_str(), ios_base::in); this->resultados.open(arq_resultados, ios_base::out); this->ht = new hashtable(8388593); // 8388593 < 2^23 stopwords = new string[335]; // while (!sw.eof()) // getline(sw, stopwords[i++]); int = 0; while (getline(this->sw, stopwords[i++])); string linha; ( = 1; !this->livro.eof(); i++) { getline(this->livro, linha); int n; string *palavras = split(linha, n); (int j = 0; j < n; j++) { if (deveguardar(palavras[j])) ht->inserir(palavras[j], i); } } } operadoraarquivos::~operadoraarquivos() { this->livro.close(); this->buscas.close(); this->resultados.close(); this->sw.close(); } bool operadoraarquivos::deveguardar(string str) { int baixo = 0, alto = 334, meio; while (baixo <= alto) { meio = (baixo + alto) / 2; if (str == stopwords[meio]) return true; else { if (str > stopwords[meio]) baixo = meio; else alto = meio; } } return false; } string operadoraarquivos::paramaiuscula(string str) { string result = ""; ( std::string::iterator it=str.begin(); it!=str.end(); ++it) result += toupper(*it); return result; } void operadoraarquivos::imprimirbusca() { string temp; while (getline(buscas, temp)) { ht->imprimir(temp); } }
operadoraarquivos.hpp
#ifndef operadoraarquivos_h #define operadoraarquivos_h #include <iostream> #include <fstream> #include <cctype> #include "hash.hpp" #define arq_resultados "resultados.txt" string* split(string str, int &n) { int contador = 0; ( string::iterator it=str.begin(); it!=str.end(); ++it) { if (*it == ' ') contador++; } string *tokens = new string[contador+1](); int = 0; (string::iterator it=str.begin(); it!=str.end(); ++it) { if (*it == ' ') i++; tokens[i] += *it; } n = + 1; return tokens; } class operadoraarquivos { private: string* stopwords; ifstream livro; ifstream sw; ifstream buscas; ofstream resultados; bool deveguardar (string str); string paramaiuscula (string str); hashtable* ht; public: operadoraarquivos(string livro, string sw, string buscas); ~operadoraarquivos(); hashtable* gethashtable(); void imprimirbusca(); }; #endif // operadoraarquivos_h
hash.cpp
#include "hash.hpp" #include "lista.hpp" hashtable::hashtable(int max) { vetorlistas = new lista<palavra>[max](); this->max = max; } hashtable::~hashtable() { delete[] vetorlistas; } int hashtable::hash (string str) { posicao indice = 0; int expoente = 0; ( std::string::iterator it=str.begin(); it!=str.end(); ++it) indice += (*it) * pow(128,expoente++); indice %= max; } void hashtable::inserir(string texto, int linha) { palavra palavra; posicao indice = hash(texto); palavra.chave = indice; palavra.texto = texto; if (!vetorlistas[indice].vazia()) { no<palavra>* no = vetorlistas[indice].buscar(palavra); if (!no) { palavra.lista = new lista<int>(); palavra.lista->inserir(linha); vetorlistas[palavra.chave].inserir(palavra); } else { no->item.lista->inserir(linha); } } else { palavra.lista = new lista<int>(); palavra.lista->inserir(linha); vetorlistas[indice].inserir(palavra); } } no<palavra>* hashtable::buscar (string texto) { palavra palavra; palavra.texto = texto; palavra.chave = hash(texto); return vetorlistas[palavra.chave].buscar(palavra); } no<palavra>* hashtable::operator[] (string texto) { return buscar(texto); } void hashtable::imprimir(string texto) { no<palavra>* no = this->buscar(texto); cout << texto << " "; no->item.lista->imprimir(); }
hash.hpp
#ifndef lista_h #define lista_h #include <iostream> using namespace std; typedef int chave; typedef int posicao; template <class t> class no { public: t item; no<t> *proximo; }; template <class t> class lista { private: no<t> *prim, *ult; void flvazia(); public: lista(); ~lista(); bool vazia(); void inserir(t x); void retira(no<t> *p); //no<t>* buscar(posicao pos); no<t>* buscar(t item); void imprimir(); //void imprimechave(item item); }; #endif
lista.cpp
#include "lista.hpp" template <class t> lista<t>::lista() { flvazia(); } template <class t> lista<t>::~lista() { while (!vazia()) retira(ult); } template <class t> void lista<t>::flvazia() { prim = new no<t>(); //prim->item = {0,0}; ult = prim; ult->proximo = null; } template <class t> bool lista<t>::vazia(){ return prim == ult; } template <class t> void lista<t>::inserir(t x) { ult->prox = new no<t>(); ult = ult->prox; ult->item = x; ult->proximo = null; } template <class t> void lista<t>::retira(no<t> *p) { if (vazia() || p == null || p->prox == null) { cout << "erro: retirada impossivel" << endl; } else { no<t> *q = p->prox; p->prox = q->prox; if (p->prox == null) ult = p; delete(q); } } /*no<t>* lista<t>::buscar(posicao pos) { int i=0; (no *p = prim; p!=null; p=p->prox) { if (pos == i) return p; ++i; } return null; }*/ template <class t> no<t>* lista<t>::buscar(t item) { (no<t> *p = prim; p!=null; p=p->prox) { if (p->item == item) return p; } return null; } /*template <class t> no<t>* lista<t>::operator[](posicao pos) { return buscar(pos); }*/ template <class t> void lista<t>::imprimir() { (no<t>* p = prim; p!=null; p=p->prox) { cout << p->item; if (p->prox!=null) cout << " "; } cout << endl; }
lista.hpp
#ifndef lista_h #define lista_h #include <iostream> using namespace std; typedef int chave; typedef int posicao; template <class t> class no { public: t item; no<t> *proximo; }; template <class t> class lista { private: no<t> *prim, *ult; void flvazia(); public: lista(); ~lista(); bool vazia(); void inserir(t x); void retira(no<t> *p); //no<t>* buscar(posicao pos); no<t>* buscar(t item); void imprimir(); //void imprimechave(item item); }; #endif
two problems:
you define
split
in header file. avoid multiple definition errors, either move definition source file (leaving declaration in header), or markinline
.you're implementing templates,
hash
,lista
, in source files. template needs implemented in header, included every source file needs use template.
see this question gory details of second point.
Comments
Post a Comment