PDA

Visualizza la versione completa : [C++] Errore in compilazione "Undefined reference to..."


Gianni91
30-12-2011, 11:17
Ragazzi scusate,
dovrei provare degli esercizi,tramite del codice fatto dal mio prof.Il problema che non riesco a compilare mi da sempre
" [Linker error] undefined reference to `IntGenTree::esercizio(BaseGenTree<int>::Node*)' ".Non riesco a trovare una soluzione..
Qualcuno pu aiutarmi??
Vi posto il codice..
IntGenTree.h


#ifndef INTGTREE_H
#define INTGTREE_H

#include "BaseGenTree.h"

class IntGenTree: public BaseGenTree<int>{
protected:
/* inserire qui le intestazioni */
static void esercizio(Node* t);
public:
/* inserire qui le intestazioni pubbliche */
void _esercizio(){esercizio(root);}

};

#endif

IntGenTree.cpp


#include "IntGenTree.h"
#include "BaseGenTree.h"

/* Inserire qui il codice */

void IntGenTree::esercizio(Node* t, int& max){
if (t == NULL) { max = 0; return 0; }
// maxC = massimo tra i discendenti
// maxS = massimo tra i prossimi fratelli
int maxC, maxS;
int count;
count = countDescendantsRulers(t->firstChild, maxC);
count += countDescendantsRulers(t->nextSibling, maxS);
// max = max(t->info, maxC, maxS) = massimo globale
if (t->info > maxC){
// il nodo domina i suoi discendenti:
count++;
max = (t->info > maxS) ? t->info : maxS;
}
else
max = (maxC > maxS) ? maxC : maxS;
return count; }


BaseGenTree.h


#ifndef BASEGTREE_H
#define BASEGTREE_H

#include <iostream>
#include <iomanip>

// Necessarie per le dichiarazioni 'friend'.
template <class T> class BaseGenTree;
template <class T> std::ostream& operator<<(std::ostream&, const BaseGenTree<T>&);
template <class T> std::istream& operator>>(std::istream&, BaseGenTree<T>&);

/**
* Classe modello di un albero binario semplice.
*/
template <class T>
class BaseGenTree{
protected:

/**
* Un nodo dell'albero.
*/
struct Node{

T info; /**< Il contenuto del nodo */
Node* firstChild; /**< Il puntatore al primo figlio */
Node* nextSibling; /**< Il puntatore al prossimo fratello */

/**
* Costruisce un nodo di valore x.
*/
Node(const T& x) : info(x), firstChild(NULL), nextSibling(NULL){};
};

Node* root; /**< Il puntatore alla radice dell'albero */

static void deleteTree(Node*&);
static std::ostream& putTo(const Node*, std::ostream&);
static std::istream& getFrom(Node*&, std::istream&);
public:
/**
* Costruisce un albero binario vuoto.
*/
BaseGenTree() : root(NULL){};
/**
* Distrugge l'albero binario.
*/
virtual ~BaseGenTree() {deleteTree(root);};

friend std::ostream& operator<< <>(std::ostream&, const BaseGenTree<T>&);
friend std::istream& operator>> <>(std::istream&, BaseGenTree<T>&);
};



/* =============== IMPLEMENTAZIONE =============== */

/**
* Cancella tutti i nodi dell'albero t.
*/
template <class T>
void BaseGenTree<T>::deleteTree(Node*& t) {
if (t != NULL) {
deleteTree(t->firstChild);
deleteTree(t->nextSibling);
delete t;
t = NULL;
}
}

/**
* Invia un albero su stream di output nel formato: [1[3][4[][5]]].
*/
template <class T>
std::ostream& BaseGenTree<T>::putTo(const Node* t, std::ostream& os){
os << '[';
if(t != NULL)
{
// stampo la radice:
os << t->info;
// stampo i sottoalberi:
for(Node* i = t->firstChild; i != NULL; i = i->nextSibling)
putTo(i, os);
}
os << ']';
return os;
}

/**
* Ridefinizione dell'operatore 'put to' per la classe BaseGenTree.
* Invia un albero su stream di output nel formato: [1[3][4[][5]]].
*/
template<class T>
std::ostream& operator<<(std::ostream& os, const BaseGenTree<T>& t){
return BaseGenTree<T>::putTo(t.root, os);
}

/**
* Acquisisce un albero da stream di input nel formato: [1[3][4[][5]]].
*/
template <class T>
std::istream& BaseGenTree<T>::getFrom(Node*& t, std::istream& is){
deleteTree(t);

char cbuf;
is >> cbuf;
if (cbuf != '['){
is.putback(cbuf);
is.clear(std::ios_base::failbit);
return is;
}
is >> cbuf;
if (cbuf == ']') // albero vuoto: []
return is;
is.putback(cbuf);
T info;

is >> info >> cbuf;
if (is.fail()) return is;
t = new Node(info);
Node** subTree = &(t->firstChild);
while (cbuf == '['){
// acquisisco un sottoalbero:
is.putback(cbuf);
getFrom(*subTree, is);
is >> cbuf;
subTree = &((*subTree)->nextSibling);
if (cbuf == ']'){
return is;
}
}
return is;
}

/**
* Ridefinizione dell'operatore 'get from' per la classe BaseGenTree.
* Acquisisce un albero da stream di input nel formato: [1[3][4[][5]]].
*/
template <class T>
std::istream& operator>>(std::istream& is, BaseGenTree<T>& t){
return BaseGenTree<T>::getFrom(t.root, is);
}

#endif

main.cpp


#include "IntGenTree.h"
using namespace std;

int main(){
IntGenTree t;
cout<<t<<endl;
t._esercizio();
system("PAUSE");
return 0;
}

Grazie.. :ciauz:

oregon
30-12-2011, 11:29
Quale ambiente/compilatore hai usato?

Che tipo di progetto?

Quali file hai inserito nel progetto?

Gianni91
30-12-2011, 11:41
Ho quello che usiamo all'uni,il Dev c++
Ho creato un nuovo progetto con il main e poi ho aperto all'interno anche gli altri file .h,.cpp
e ho compitalo,quando ho avviato il costruttore della classe,mi ha dato.Ma quando provo l'esercizio mi da errore...
Ho inserito tutti i file che ho postato..
grazie

oregon
30-12-2011, 11:55
Nella classe IntGenTree non esiste un metodo con la firma

esercizio(Node* t, int& max)

E inoltre questo metodo dichiarato void ma restituisce un valore con

return count;

Gianni91
30-12-2011, 12:02
Rigurado al ritorno della funzione hai perfettamente ragione,non mi ero accorto da che ho provato impostazioni diverese,ma questo purtroppo npon risolve il problema.
Il prima caso sicuramente il problema...
Sapresti dirmi cosa modificare in modo pi esplicito,da che dato che IntBeenTree una Classe figlia della classe BaseBeenTree,non ho molta dimestichezza con ereditarieta di classe ecc..
Ho provato ma non mi va,tra l'altro ho provato altre funzioni oltre a quella citata,ma ho sempre lo stesso problema(anche con esercizio(Elem* l),senza altri valori..
Grazie

LeaderGL
30-12-2011, 12:22
se nel .H il metodo si chiama "_esercizio(...)" e nel .C tu fai riferimento ad "esercizio(...)" senza il trattino basso iniziale ti dar sempre problemi in compilazione.

Correggi il nome in uno dei due files.

Gianni91
30-12-2011, 12:27
Guarda non vorrei sbagliarmi,ma nel file c' anche un _esercizio(),con all'interno una chiamata a esercizio(Elem*)...

oregon
30-12-2011, 12:32
Ti ripeto .. il problema che nella classe c' il metodo

esercizio(Node* t)

ma nell'implementazione tu scrivi

esercizio(Node* t, int& max)

Adesso sta a te capire perch quel parametro

int& max

in pi.

Gianni91
30-12-2011, 12:51
Ragazzi ho fatto in questo modo,ma niente :dh:


#ifndef INTGTREE_H
#define INTGTREE_H

#include "BaseGenTree.h"

class IntGenTree: public BaseGenTree<int>{
protected:
/* inserire qui le intestazioni */
static void esercizio(Node*,int);
public:
/* inserire qui le intestazioni pubbliche */
void _esercizio();

};

#endif





/* Inserire qui il codice */

void IntGenTree::esercizio(Node* t,int max){
if (t == NULL) { max = 0; return 0; }
// maxC = massimo tra i discendenti
// maxS = massimo tra i prossimi fratelli
int maxC, maxS;
int count;
count = countDescendantsRulers(t->firstChild, maxC);
count += countDescendantsRulers(t->nextSibling, maxS);
// max = max(t->info, maxC, maxS) = massimo globale
if (t->info > maxC){
// il nodo domina i suoi discendenti:
count++;
max = (t->info > maxS) ? t->info : maxS;
}
else
max = (maxC > maxS) ? maxC : maxS;
return count; }


void IntGenTree::_esercizio(){ int n=5;
esercizio(root,n);
}

Gianni91
30-12-2011, 19:13
Provato anche a cancellarei file di compilazione e a creare un nuovo progetto..
niente.

Loading