Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    multiple definition error c++

    Salve.
    Ho un file .h (FileReader.h)che è incluso da 2 files .cpp (main.cpp e FileReader.cpp) .
    FileReader.h a sua volta è definito :

    #ifndef FILEREADER_H
    #define FILEREADER_H
    #include <fstream> // file stream
    #include <iostream>
    #include <string>
    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <map> // inclusione template map
    #include <algorithm>
    #include <cstdlib>

    #include <grafo/GrafoNonOrientato_MatriceAdiacenza.h>
    ecc...

    grafo/GrafoNonOrientato_MatriceAdiacenza.h include :
    #ifndef _GRAFONONORIENTATO_MATRICEADIACENZA_H
    #define _GRAFONONORIENTATO_MATRICEADIACENZA_H

    #include <grafo/GrafoNonOrientato.h>
    #include <grafo/Grafo_MatriceAdiacenza.h>

    GrafoNonOrientato.h e Grafo_MatriceAdiacenza.h includono entrambi il file Grafo.h

    Il problema è che il compilatore (dev c++) mi da errori di "multiple definition" delle classi appartenenti ai .h:
    multiple definition of `asd::Grafo::Grafo()'
    multiple definition of `asd::Grafo::~Grafo()'
    ecc.....

  2. #2

  3. #3

    Grafo

    Il costruttore e il distruttore di Grafo li definisco nel file Grafo.h dove è dichiarata la classe Grafo con i suoi metodi:

    #ifndef _GRAFO_H
    #define _GRAFO_H

    #include <ext/hash_map>
    #include <list>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cassert>


    namespace asd {

    class vertice;
    class arco;
    class hash_v;
    template<class T> class vertice_array;
    template<class T> class arco_array;
    class adiacente;
    class Grafo;

    /*
    Vertice di un grafo
    */
    class vertice
    {
    public:
    vertice()
    {}

    ~vertice()
    {}
    };



    /*
    Arco di un grafo
    */
    class arco
    {
    public:
    vertice* sorg;
    vertice* dest;
    int costo;

    public:
    arco(vertice* a = 0, vertice* b = 0, int costo = 0)
    : sorg(a),
    dest(b),
    costo(costo)
    {}

    ~arco()
    {}

    vertice* opposto(vertice* v)
    {
    if(v == sorg) return dest;
    return sorg;
    }

    bool incideSu(vertice* v)
    {
    if(v==sorg || v==dest) return true;
    return false;
    }
    };



    class hash_v: std::unary_function<vertice*,long>
    {
    public: long operator()(vertice* x) const
    {
    return (long)x;
    }

    public: long operator()(arco* x) const
    {
    return (long)x;
    }
    };



    /*
    Contenitore associativo per vertici.
    */
    template<class T>
    class vertice_array
    : public __gnu_cxx::hash_map< vertice*, T, hash_v >
    {
    public:
    vertice_array()
    : __gnu_cxx::hash_map< vertice*, T, hash_v >()
    {}

    ~vertice_array()
    {}
    };



    /*
    Contenitore associativo per archi.
    */
    template<class T>
    class arco_array
    : public __gnu_cxx::hash_map< arco*, T, hash_v >
    {
    public:
    arco_array()
    : __gnu_cxx::hash_map< arco*, T, hash_v >()
    {}

    ~arco_array()
    {}
    };



    class adiacente
    {
    public:
    vertice* vertex;
    int costo;

    adiacente(vertice* vert = 0, int c = 0)
    : vertex(vert),
    costo(c)
    {}

    ~adiacente()
    {}
    };



    /*
    Classe astratta che definisce una versione generica di grafo.
    */
    class Grafo
    {
    protected: // dati protected
    unsigned vertexCount;
    unsigned edgeCount;

    public: // dati public
    std::list< vertice* > lista_vertici;
    std::list< arco* > lista_archi;

    // metodi definiti
    public: // operazioni
    Grafo();
    virtual ~Grafo();

    unsigned numVertici() const;
    unsigned numArchi() const;

    vertice* estremi(arco* e) const;
    vertice* opposto(vertice* x, arco* e) const;
    vertice* aggiungiVertice();
    arco* aggiungiArco(vertice* x, vertice* y, int costo);
    void rimuoviVertice(vertice* v);
    void rimuoviArco(arco* e);
    void clear();
    void genera_random(unsigned n, unsigned m, int costo_max, bool loopfree = false);

    // metodi virtuali
    public:
    virtual unsigned grado(vertice* v) const;
    virtual void archiIncidenti(vertice* v, std::vector<arco*> &vec) const;

    // metodi virtuali puri
    public:
    virtual void inserisciVertice(vertice* v) = 0;
    virtual void inserisciArco(arco* e) = 0;
    virtual void eliminaVertice(vertice* v) = 0;
    virtual void eliminaArco(arco* e) = 0;
    virtual void reset() = 0;
    virtual bool sonoAdiacenti(vertice* x, vertice* y) const = 0;
    virtual bool diretto() const = 0;
    virtual void verticiAdiacenti(vertice* v, std::vector<vertice*> &vec) const = 0;
    virtual void verticiAdiacenti(vertice* v, std::vector<adiacente> &vec) const = 0;

    public: // typedefs
    typedef std::list< vertice* >::iterator vertice_iterator;
    typedef std::list< vertice* >::const_iterator vertice_const_iterator;
    typedef std::list< vertice* >::reverse_iterator vertice_rev_iterator;
    typedef std::list< vertice* >::const_reverse_iterator vertice_const_rev_iterator;
    typedef std::list< arco* >::iterator arco_iterator;
    typedef std::list< arco* >::const_iterator arco_const_iterator;
    typedef std::list< arco* >::reverse_iterator arco_rev_iterator;
    typedef std::list< arco* >::const_reverse_iterator arco_const_rev_iterator;
    };



    /* PUBLIC */

    /*
    Costruttore.
    */
    Grafo::Grafo()
    : vertexCount(0)
    , edgeCount(0)
    {

    }



    /*
    Distruttore.
    */
    Grafo::~Grafo()
    {
    vertice* v;
    for_each_vertice(v,(*this)) delete v;

    arco* e;
    for_each_arco(e,(*this)) delete e;
    }



    /*
    Restituisce il numero di vertici presenti nel grafo.
    */
    unsigned Grafo::numVertici() const
    {
    return vertexCount;
    }



    /*
    Restituisce il numero di archi presenti nel grafo.
    */
    unsigned Grafo::numArchi() const
    {
    return edgeCount;
    }



    /*
    Restituisce gli estremi x e y dell'arco e = (x, y).
    */
    vertice* Grafo::estremi(arco* e) const
    {
    static bool prima_chiamata = true;

    if (prima_chiamata) {
    prima_chiamata = false;
    return e->sorg;
    }
    else {
    prima_chiamata = true;
    return e->dest;
    }
    }



    /*
    Restituisce y, l'estremo dell'arco e = (x, y) diverso da x.
    */
    vertice* Grafo:pposto(vertice* x, arco* e) const
    {
    if (e->dest != x) return e->dest;
    else return e->sorg;
    }




    /*
    Inserisce un nuovo vertice v.
    */
    vertice* Grafo::aggiungiVertice()
    {
    vertice* v = new vertice();

    inserisciVertice(v);
    lista_vertici.push_back(v);
    ++vertexCount;

    return v;
    }



    /*
    Inserisce un nuovo arco tra i vertici x e y.
    */
    arco* Grafo::aggiungiArco(vertice* x, vertice* y, int costo = 1)
    {
    arco* e = new arco(x, y, costo);

    lista_archi.push_back(e);
    inserisciArco(e);

    ++edgeCount;

    return e;
    }



    /*
    Rimuove il vertice v dal grafo.
    */
    void Grafo::rimuoviVertice(vertice* v)
    {
    eliminaVertice(v);

    arco_iterator i, j;
    for (i = lista_archi.begin(); i != lista_archi.end(); )
    {
    if ((*i)->sorg == v || (*i)->dest == v)
    {
    j = i;
    ++j;
    delete *i;
    lista_archi.erase(i);
    --edgeCount;
    i = j;
    }
    else ++i;
    }

    vertice_iterator k;
    for (k = lista_vertici.begin(); *k != v; ++k) ;
    lista_vertici.erase(k);
    delete v;

    --vertexCount;
    }



    /*
    Rimuove l'arco e dal grafo.
    */
    void Grafo::rimuoviArco(arco* e)
    {
    eliminaArco(e);

    arco_iterator i;
    for (i = lista_archi.begin(); *i != e; ++i) ;
    lista_archi.erase(i);
    delete e;

    --edgeCount;
    }



    /*
    Elimina tutti i vertici e tutti gli archi, rendendo il grafo vuoto.
    */
    void Grafo::clear()
    {
    vertice* v;
    for_each_vertice(v,(*this)) delete(v);

    arco* e;
    for_each_arco(e,(*this)) delete(e);

    reset();

    lista_vertici.clear();
    lista_archi.clear();

    vertexCount = 0;
    edgeCount = 0;
    }



    /*
    Genera casualmente il grafo, con n vertici, m archi,
    il cui costo e' nell'intervallo [1, costo_max].
    La variabile booleana 'loopfree' si riferisce
    alla presenza(false) o no(true) di self-loops.
    */
    void Grafo::genera_random(unsigned n, unsigned m, int costo_max, bool loopfree)
    {
    assert( !( n == 0 && m > 0 ) );
    assert( !( n == 1 && m > 0 && loopfree ) );

    std::vector<vertice*> V(n);
    std::vector<int> deg(n);
    unsigned i, j;
    int d;

    clear();

    for (i = 0; i < n; ++i) {
    V[i] = aggiungiVertice();
    deg[i] = 0;
    }
    for (i = 0; i < m; i++) {
    deg[rand() % n]++;
    }
    for (i = 0; i < n; i++) {
    vertice* v = V[i];
    d = deg[i];
    while ( d > 0 ) {
    j = rand() % n;
    if ( loopfree && j == i ) continue;
    aggiungiArco(v, V[j], 1 + (rand() % costo_max));
    d--;
    }
    }
    }



    /*
    Restituisce il grado del vertice v
    */
    unsigned Grafo::grado(vertice* v) const
    {
    unsigned g = 0;

    arco* e;
    for_each_arco(e,(*this))
    if(e->incideSu(v))
    ++g;

    return g;
    }



    /*
    Riempie il vector vec con gli archi incidenti a v.
    */
    void Grafo::archiIncidenti(vertice* v, std::vector<arco*> &vec) const
    {
    arco* e;
    for_each_arco(e,(*this))
    if(e->incideSu(v))
    vec.push_back(e);
    }




    } // namespace asd


    #endif /* _GRAFO_H */

  4. #4

    multiple error

    In pratica il mio programma è strutturato così:

    ho 2 files .cpp che includono il mio .h.

    Il mio .h include i altri 2 .h

    Questi 2 . h includono entrambi Grafo.h

  5. #5

    Re: multiple error

    Originariamente inviato da wnocella
    In pratica il mio programma è strutturato così:

    ho 2 files .cpp che includono il mio .h.

    Il mio .h include i altri 2 .h

    Questi 2 . h includono entrambi Grafo.h
    Sposta la definizione dei metodi da Grafo.h a Grafo.cpp.

  6. #6

    linker error

    Ciao .
    Ho fatto come hai detto tu. Ho separato i prototipi delle fun<ioni dalle implementazioni.
    Quindi per ogni file . h ho creato un file .cpp e ci ho messo le implementazioni più l'include del riSPETTIVO .h ;

    Però adesso mi da 1 altro problema:

    [Linker error] undefined reference...

    Praticamente me lo fa per alcuni metodi e costruttori.

  7. #7

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.