Newsgroup: it.comp.lang.c++
Titolo: Problema in questo frammento...xkè?

Ciao a tutti, giorni fà ho postato un msg su cui mi lamentavo di nn trovare
l'errore...
mi è stato consigliato di postare il codice...
eccolo qua... francamente nn capisco proprio il motivo delle lamentele del
compilatore (scusate l'ignoranza, e ci vedo pure all'università x nn capirne
nulla )
//*******************************************************
#ifndef TREE_H
#define TREE_H
#include <iostream>
#include <iomanip>
#include <cstdlib>
class BinNode {
   friend class N_Node;
   friend ostream &operator<< ( ostream &, const BinNode * );
   friend istream &operator>> ( istream &, BinNode * );   // Parser ( 0<=
val <= 9 )
   public:
      BinNode() { val=0; lson=rson=NULL; };
      BinNode ( const N_Node * );                               // it's
Kin!!
      ~BinNode();
      int val;
      BinNode *lson, *rson;
};
class N_Node {
   friend class BinNode;
   friend ostream &operator<< ( ostream &, const N_Node * );
   friend istream &operator>> ( istream &, N_Node * );   // Parser ( 0<= val
<= 9 )
   public:
      N_Node() { val=0; son=nxt=NULL; };
      N_Node ( const BinNode * );                               // it's
Hin!!
      ~N_Node();
      int val;
      N_Node *son, *nxt;
};
class BinTree {
   friend class N_Tree;
   friend ostream &operator<< ( ostream &out, const BinTree &btree )
          { out << btree.root; return out; };
   friend istream &operator>> ( istream &, BinTree & );
   public:
    BinTree() { root=NULL; };
/*line 47*/    BinTree ( const N_Tree ntree ) { root = new BinNode(
ntree.root ); };// starts Kin!!
    ~BinTree() { delete root; };
   private:
    BinNode* root;
};
class N_Tree {
   friend class BinTree;
   friend ostream &operator<< ( ostream &out, const N_Tree &ntree )
          { out << ntree.root; return out; };
   friend istream &operator>> ( istream &, N_Tree & );
   public:
    N_Tree() { root=NULL; };
    N_Tree ( const BinTree btree ) { root = new N_Node( btree.root ); };//
starts Hin!!
    ~N_Tree() { delete root; };
   private:
    N_Node* root;
};
#endif
//************
errore:
47 D:\Univ\ASD\Kin_Hin\tree.h
parameter `ntree' has incomplete type
//
perchè?
Aiutatemi, aiutooooooooooooooooooo!
Daniele

 ntree.root ); };// starts Kin!!
semplicemente N_Tree è ancora un tipo indefinito, perchè viene definito
più sotto. Il compilatore ad esempio non potrebbe sapere se root è
effettivamente un membro di N_Tree. La soluzione è di dichiarare prima
N_Tree. 
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


ma se dichiaro prima N_Tree, risulta indefinito BinTree (se dai uno sguardo
t accorgi che le definizioni sono simmetriche)
allora metto prima l'uovo o la gallina?
Dan

 allora metto prima l'uovo o la gallina?
prima dichiari, poi definisci.
NB.: mancano tutti gli identificatori di namespace (std::) davanti a
ostream, istream e a quant'altro. Sicuro che non ottieni errori qui? che
compilatore usi?
#ifndef TREE_H
#define TREE_H
#include <iostream>
#include <iomanip>
#include <cstdlib>
class N_Node;
class BinNode
{
   friend class N_Node;
   friend ostream& operator << (ostream&, BinNode const*);
   friend istream& operator >> (istream&, BinNode*);
public:
   BinNode();
   BinNode (N_Node const*); // it's Kin!!
   ~BinNode();
   // queste sotto dovrebbero essere private, ma te le lascio così.
   int val;
   BinNode* lson, *rson;
};
class N_Node
{
   friend class BinNode;
   friend ostream& operator << (ostream&, N_Node const*);
   friend istream& operator >> (istream&, N_Node*);
public:
   N_Node();
   N_Node (BinNode const*); // it's Hin!!
   ~N_Node();
   int val;
   N_Node* son, *nxt;
};
class BinTree 
{
   friend class N_Tree;
   friend ostream& operator << (ostream& out, BinTree const& btree);
   friend istream& operator >> (istream&, BinTree&);
public:
   BinTree();
   BinTree (N_Tree const& ntree);
   ~BinTree();
private:
   BinNode* root;
};
class N_Tree
{
   friend class BinTree;
   friend ostream& operator << (ostream& out, N_Tree const& ntree);
   friend istream& operator >> (istream&, N_Tree&);
public:
   N_Tree();
   N_Tree (BinTree const& btree);
   ~N_Tree();
private:
   N_Node* root;
};
#endif
ok? questo è il file Tree.h.
Aggiungi un file Tree.cpp (per esempio) dove metterai le definizioni. A
questo punto non dovresti più avere problemi (a parte la nota che ti ho
fatto all'inizio).


e adesso cos'č che nn va?
32 D:\Univ\ASD\Kin_Hin\ntree.h
    invalid use of undefined type `class BinTree'
25 D:\Univ\ASD\Kin_Hin\ntree.h
    forward declaration of `class BinTree'
44 D:\Univ\ASD\Kin_Hin\ntree.h
    parse error before `*'
47 D:\Univ\ASD\Kin_Hin\ntree.h
    ANSI C++ forbids declaration `son' with no type
    `bnode' was not declared in this scope
e errori a cascata fino alla fine del frammento causati dal parse error in
line 44...
Xkč? Perchč?  nn ne ho la + pallida idea!
Daniele
PS, sono disperato :-)

 fatto, idem stesso errore...
sì, ma devi tenere anche conto di quanto ti ho detto nel post precedente!
non puoi utilizzare un tipo se non l'hai nemmeno dichiarato. 
Ora non ti correggerò gli errori uno per uno, ma come linea guida
ricordati che se scrivi qualcosa come
Classe* puntatore
di Classe *deve* esistere almeno la forward declaration:
class Classe;
Classe* puntatore;
per accedere alle funzioni private di Classe devi avere invece la
definizione della Classe completa visibile nel punto in cui la usi. Ovvero
class Classe;
void f (Classe* puntatore)
{
   puntatore->f ();
}
solleverà un errore, perchè Classe non è definita in quel punto. Invece:
class Classe
{
public:
   int f ();
};
void f (Classe* puntatore)
{
   puntatore->f ();
}
compilerà correttamente. Ora rifletti su quanto detto, leggi i post e fai
le tue prove e, soprattutto, leggi il tuo manuale di C++ (ne hai uno,
VERO?)perchè queste sono le problematiche base.


 nulla )
Ah ma allora ce rifai? Daniè pure io avevo un problema del genere
con ntree e liste di ntree...se dichiaro prima uno l'altro non sa che fare e
viceversa! la soluzione che ho trovato è un pò una zozzata ma funziona!
Tu dichiari lista di ntree che è una lista di puntatori non a ntree, ma a
void.
Poi nel costruttore della lista fai lo static_cast<nt*> del puntatore
a void.
--
Emanuele Di Saverio
---------------------------------------------
Remove NOSPAM manually for reply
Scusate le vaccate se  ne dico!

 compilatore usi?
gcc++ per windows (dev c++) se ne fotte altamente. Infatti sto prendendo
brutte abitudini...


 Non ho capito mi potresti spiegare con una classe-esempio + semplice?
uff... allora:
<codice non funzionante>
class A
{
public:
   int f (B* b_ptr)
      {   return b_ptr->f (); }
   int g ()   {   return 0; }
};
////----
class B
{
   A* a_ptr;
public:
   B (A* ptr): a_ptr (ptr) { }
   int f ()
      {   return a_ptr->g (); }
};
</codice non funzionante>
non funziona, siamo tutti d'accordo? Non funziona perchè in A::f b_ptr
appartiene ad un tipo non ancora definito. Se spostiamo la definizione di
B sopra ad A non funziona comunque perchè A::g non sarebbe ancora
definita. Quindi si scrive:
<codice funzionante>
class B;
class A
{
public:
   int f (B* b_ptr);
   int g ()   {   return 0; }
};
class B
{
   A* a_ptr;
public:
   B (A* ptr): a_ptr (ptr) { }
   int f ()
      {   return a_ptr->g (); }
};
// in questo punto sia la classe B che la classe A 
// sono definiti, quindi stavolta il codice compila 
// (o almeno dovrebbe).
int A::f (B* b_ptr)   {   return b_ptr->f (); }
</codice funzionante>
spero di essermi spiegato (credo di essermi un po' rimbambito ultimamente,
sorry).


si, ma nel mio caso tutti e due gli oggetti sono in corrispondenza, ognuno č
definito in base all'altro quindi nn ce ne č uno che viene prima... nn penso
che questa strada sia praticabile, hai altre idee?
Danz


Aah ma certo! Scusa se ti ho fatto perdere tempo, è tutto chiaro ora.


 che questa strada sia praticabile, hai altre idee?
dai un occhiata all'altro post in questo thread, c'è un esempio di come si
fa quello che vuoi fare tu.
