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
splitin 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