Newsgroup: it.comp.lang.c++
Titolo: visibilita' attributi --> classe

salve a tutti, ho un dubbio come da subject:
avendo una classe con attributi di un'altra classe del tipo:
class foo_class
{
	private:
		// ...
		bar_class bar_obj;
	public:
		// ...
		void function();
}
di cui dichiaro (per es. in un main) un'istanza come:
main()
{
	foo_class foo_obj;
	// ...
}
e` possibile chiamare foo_obj.function() DA un metodo di bar_obj ?
dal manuale direi di no, dato che metodi e attributi di foo_obj NON sono
nel campo di visibilita` di bar_obj, essendo proprio lui un'attributo.
a questo punto, come risolvo? ho pensato a un namespace foo, all'interno
del quale metto quelli che prima erano i metodi della classe foo_class,
definendone poi gli attributi direttamente nel main, utilizzando "using
namespace foo" sia per essi che per bar_class.
MA: da una funzione di foo riesco ora a chiamare un metodo di bar_obj ?
e` la situazione opposta, non vorrei essere incappato in un deadlock! ;)
sperando di essere stato chiaro, Giacomo
-- 
| Giacomo Jack Tenaglia @ lab: tenaglia(at)
cs.unibo.it
 <--+
`---> Ultimate Player - Rock'n'Roll Lover - Linux Powered |


Ciao Giacomo,
potresti avere nella classe bar_class un metodo che abbia come parametro un
puntatore  pfoo a foo_class e con questo chiamare function():
class bar_class
{
private:
// ...
public:
void func(foo_class *pfoo) {pfoo->function();}
}
Maurus

}
si, ma resta il problema di cosa passare a func(???), dato che le
istanze di bar_class sono *loro stesse* attributi di foo_class, e che
quindi "non sanno il nome" dell'oggetto che li chiama..
ciao, Giacomo



Mi dovresti fare un esempio concreto di cosa non puoi fare.
Penso che risolveresti il tuo problema dichiarando friend la classe
foo_class all´interno di bar_class e viceversa, ma se mi fai un esempio e´
meglio.
Per il momento puoi riuscire a chiamare il metodo function() della classe
foo_class attraverso il metodo func() di bar_class.
Se mi facessi vedere cosa non riesci a fare magari andiamo piu´ nel
dettaglio.
Maurus

 >quindi "non sanno il nome" dell'oggetto che li chiama..
Da quello che ho capito, quello che cerchi di fare e' di chiamare
foo_class::function() dall'interno di bar_class.
Quello che ti serve e' un riferimento in bar_class dell'oggetto foo_class.
es: (non compilato in quanto non ho un compilatore c++ dove mi trovo al
momento)
class foo_class;
class bar_class {
   foo_class *pfoo;
public:
   bar_class (foo_class *_pfoo): pfoo(_pfoo) {}
};
Nella classe foo_class, poi puoi  inizializzare bar_class con this.
This e' garantito anche se la classe non e' stata completamente costruita.
Alex

meglio.
infatti forse e` la soluzione migliore, comunque ecco un esempio (piu`
comprensibile spero):
class auto
{
	private:
		engine_class motore;
		fuel_class serbatoio;
		// ...
	public:
		auto();
		~auto();
		avvia();
		guasto();
		// ...
}
class engine_class
{
	private:
		bool acceso;
		// ...
	public:
		engine_class();
		~engine_class();
		start();
		stop();
		check_grip();
		// ...
}
main()
{
	// qui vengono chiamati anche i	costruttori di motore,
	// serbatoio..
	auto la_mia_macchina;
	la_mia_macchina.avvia();
	// ...
}
ora, la funzione avvia() chiamera` anche la funzione motore.start() che
pero` se rileva un guasto (con check_grip() ad esempio), deve richiamare
la funzione guasto() di la_mia_macchina. il tutto senza usare eccezioni.
sperando nella chiarezza, Giacomo



Personalmente applicherei i patterns "Composite" e "Chain of Responsability"
Ref: Gamma Design Patterns.
Se non hai il libro sotto mano, darei un'occhiata su internet.
Dal punto di vista tecnico, come ho scritto nel messaggio precedente, per
fare in modo che motore possa chiamare un metodo di macchina, deve prima di
tutto sapere di che macchina fa parte, e quindi ha bisogno di un mantenere
un puntatore alla macchina che lo contiene.
Alex

un puntatore alla macchina che lo contiene.
esatto, e` cosi`, quindi sarebbe:
class auto;
class engine_class {
   auto *myauto;
   public:
      engine_class (auto *ref_auto): myauto(ref_auto) {}
      };
..e come dovrei dichiarare (in un mai() ad esempio) un oggetto di classe
auto? semplicemente con:
auto macinino;
(penso di si`..), allora in class auto avro` avro` :
class auto
{
	private:
		engine_class motore(auto);
}
..o qualcosa di simile no?
ciao, Giacomo


 }
Non esattamente.
In class auto (che peraltro e' una parola chiave e che quindi non va bene!)
hai un oggetto motore.
Il costruttore di auto deve occuparsi di inizializzare engine_class motore.
es:
class autom;
class engine_class motore {
    private:
        autom *p_autom;
    public:
        engine_class (autom *_ptr_to_autom):p_autom (_ptr_to_autom){}
};
class autom {
    engine_class motore;
public:
    autom (): motore (this) {};
};
Alex

quindi "non sanno il nome" dell'oggetto che li chiama..
L'unico modo e' che il membro "conosca" l'oggetto che lo contiene
e questo si puo' fare passando "this" dell'oggetto durante la
costruzione del membro.
Usare il puntatore this durante la costruzione di un oggetto
e' lecito... ma non essendo l'oggetto ancora costruito bisogna
stare attenti a quello che ci si fa... se chi riceve il "this"
di un oggetto in costruzione dovesse chiamare metodi dell'oggetto
ci sarebbero casini. Memorizzare "this" per usarlo in seguito e'
invece ok...
   #include <iostream>
   class bar; // forward
   class foo
   {
     private:
       bar& owner;
     public:
       foo(bar& o) : owner(o)
       { }
       void call_owner();
   };
   class bar
   {
     public:
       int x;
       foo f;       
       void a_function()
       {
         std::cout << "bar[" << this << "]::a_function...\n";
       }
 
       bar() : x(6502),f(*this)
       { }
   };
   void foo::call_owner()
   {
     std::cout << "foo[" << this << "]::call_owner()\n";
     owner.a_function();
   }
   int main()
   {
     bar b1,b2;
     b1.f.call_owner();
     b2.f.call_owner();
     return 0;
   }
HTH
Andrea
PS:
  VC++ ad esempio genera un warning con usi di questo tipo
  di 'this' nella initialization list.
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

invece ok...
e se invece usassi un namespace ? sarebbe molto piu` facile chiamarne le
funzioni.. pero` cosi` come potrei chiamare un metodo specifico di un
oggetto DAL namespace? sempre usando this?


};
stai solo attento che nel costruttore di engine_class non devi
assolutamente eseguire alcuna operazione su _ptr_to_autom, perché in
quel momento punta ad un oggetto non completamente costruito. Inoltre
_ptr_to_autom è un nome riservato al compilatore.
Anto
--
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it