Newsgroup: it.comp.lang.c++
Titolo: Classi dentro classi

Salve a tutti,
vi scrivo per chiedervi qualche consiglio sulla progettazione di
alcune classi che dovrò poi utilizzare all'interno di un mio
programma.
Semplificando il tutto passo a descrivere il mo problema:
Classi
Piano:	Contiene i dati relativi ad un piano di una struttura in
	muratura
Telaio:	Contiene i dati relativi ad un muro di un piano
Apertura: Contiene i dati relativi ad una apertura (finestra, porta, 
	  ecc) di un muro.
Ho deciso di creare una classe per ogniuno di questi elementi perchè
hanno caratteristiche proprie che a mio avviso bene si prestano alla
definizione di oggetto e poi inserire tutti gli elementi in un'unica
classe (ad esempio Piano) sarebbe stato troppo caotico e poco
gestibile.
La classe Piano oltre a contenere dati specifici contiene anche N
oggetti di tipo Telaio che ho pensato di organizzare in una lista per
poterne dinamicamente aggiungere o eliminare.
La classe Telaio oltre a contenere dati specifici contiene anche M
oggetti di tipo Apertura anche questi organizzati in una lista.
Il consiglio che cerco riguarda l'accessibilità delle funzioni membro
delle classi interne da perte dell'utilizzatore finale; l'unica classe
disponibile sarà la classe Piano e vorrei sapere secondo voi quale
sarebbe il metodo migliore per consentire di settare i dati dei telai
e delle aperture contenute nella classe.
Devo forse scrivere, per la classe Piano, tutte le funzioni per
accedere ai dati delle classi interne?
Queste funzioni non farebbero altro che richiamare le funzioni membro
della classe Telaio che a loro volta richiamerebbero le funzioni
membro della classe Apertura, non pensate che otterrei così una classe
Piano con un'infinità di metodì?
C'è un metodo migliore?
Ringrazio tutti quelli che vorranno aiutarmi 
Ciao
		Pevar...
           Pevar...
---------------------
pe...@dada.mail.it

 wrote in message 37e1092...@news.dada.it...


 Piano con un'infinità di metodì?
E' una possibilità, ma forse si può progettare meglio. Magari potresti porre
all'esterno le dichiarazioni di classi, in modo da poter gestire tutti i
metodi/proprietà. La classe Piano, a questo punto, avrebbe un metodo
AggiungiTelaio(telaio *puntatore), o qualcosa del genere. A questo punto
crei gli oggetti Telaio e poi li aggiungi alla lista interna di Piano.
Oppure lasci a Piano il compito di crearli, e la dichiarazione di
AggiungiTelaio prenderebbe come parametri quelli necessari per
l'istanziazione (al limite void).
Poi puoi fare un metodo che ti ritorna un puntatore all''oggetto telaio che
ti serve. In questo modo potresti scrivere una cosa del tipo:
piano_corrente.telaio(1)->lunghezza = 1;
Ovviamente assumendo che piano_corrente sia di tipo Piano, che esista un
metodo telaio (int n) che ti restituisce l'N-esimo telaio.
Le classi incapsulate dovrebbero essere usate nei casi in cui non serva una
visibilità all'esterno, non certo nel caso in cui descrivi, con un metodo
nella classe esterna per ogni metodo della classe interna !
Se, oltre a lavorare con l'oggetto Piano, devi avere conoscenza anche
dell'oggetto Telaio, è corretto che questa classe sia conosciuta a livello
globale, anche se poi ogni oggetto di tipo Telaio è all'interno di un Piano.
Spero di essere stato d'aiuto. Ho volutamente semplificato il discorso, ma
credo si sia capito.
--
Alessandro Monti

C'è un metodo migliore?
Faccio un esempio: supponiamo che al posto della classe Telaio
ci sia la classe Muro.
Prima di tutto dovresti chiederti se ha senso una tale strutturazione
delle classi, ovvero ha senso considerare una apertura come
oggetto a se stante cui e` possibile eseguire delle operazioni
indipendentemente da altre caratteristiche del muro cui appartiene?
Non credo che tu ad esempio possa manipolare una apertura senza tenere
conto di altre aperture sul muro. In tal caso non ha alcun senso rendere
una apertura accessibile all'esterno di un oggetto muro (ovvero
operazioni sull'apertura devono essere mediate dal muro attraverso
metodi della classe muro).
Se invece una apertura fosse manipolabile indipendentemente
dalle caratteristiche del muro (presenza di altre aperture o altro
ancora), allora probabilmente il riferimento muro-aperture e`
semplicemente una relazione fine a se stessa e in tal caso un
muro avrebbe sostanzialmente delle funzioni da contenitore.
Devi ragionare pensando ai ruoli che hanno le varie entita` ed
alle modalita` in cui esse interagiscono nei confronti
di altre entita` sia dello stesso tipo (classe) sia di tipo diverso.
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

Sarebbe più semplice rendere visibili anche le classi Telaio e Apertura.
Questo e` equivalente a rendere publici gli attributi di una classe, la
soluzione e` invece quella di analizzare i ruoli delle entita` e 
verificare (capire) se la nostra idea e` corretta o meno (anzicche`
mettere delle pezze).


credo si sia capito.
Hai semplificato un po troppo! ;)


Piano con un'infinità di metodì?
No, perchè? I metodi sarebbero quasi 3 volte di più, ma non
un'infinità. Ma la maggior parte di questi metodi si implementerebbero
semplicissimamente come chiamate ai metodi delle classi sottostanti.
Tuttalpiù, il metodo "Aggiungi_finestra" della classe piano, si occupa
di fare dei piccoli controlli sul piano prima di richiamare
"Aggiungi_finestra" della classe telaio, la quale, a sua volta
aggiungerebbe dei controlli o dei calcoli che riguardano il telaio per
chiamare, infine, la vera e propria "Aggiungi_finestra" della classe
Apertura. Mi pare invece che come metodo sia molto lineare e
organizzato. IMVHO non è male, come soluzione.
Topoldo
(Grazie a Dio, sono ateo)

 Hai semplificato un po troppo! ;)
Vero, me ne scuso. Altri sono stati più precisi, per cui spiegare meglio ora
non avrebbe senso.
--
Alessandro Monti

(uno studente è una persona), 
Uno studente non e` una persona! Sorpreso?
Il fatto e` che l'ereditarieta` (publica) esprime relazioni is-a 
permanenti, mentre quella di studente e` un ruolo che una persona
assume temporaneamente (almeno si spera).
Una situazione di questo tipo in C++ (e molti altri linguaggi OO) non va
affrontata con l'ereditarieta`.
Nella mia risposta mi riferivo proprio ad una situazione di questo
genere, ovvero verificare prima se effettivamente l'ereditarieta`
e` utilizzata correttamente dato che spesso un errore di questo genere
crea non pochi problemi.


 affrontata con l'ereditarieta`.
Ottima precisazione! Grazie.
EMG

Ottima precisazione! Grazie.
Grazie, grazie!!!!!! :)))))))
Purtroppo queste cose non le spiegano mai a lezione,
ti fanno l'esempio perche` didatticamente parlando ha
una grande qualita`... e` minimale. Peccato che pero` alla
fine potrebbero farti almeno notare la cosa!


 affrontata con l'ereditarieta`.
Concordo appieno.
Normalmente una situazione come quella da te descritta viene affrontata con
l'utilizzo del pattern State che ha proprio lo scopo di gestire il
cambiamento di comportamento (temporaneo) di un oggetto.
MM

 cambiamento di comportamento (temporaneo) di un oggetto.
C'è su Internet un posto dove posso trovare due parole su questo
pattern?
EMG

 wrote in message
news:37EA92B0...@flashnet.it...

Come riferimento base per i pattern c'e' il libro:
Design Patterns: Elements of Reusable Object-Oriented Softwareby Erich
Gamma, Richard Helm,Ralph Jonhnson, and John Vlissides
Addison Wesley. October 1994.
Non in alternativa al libro, puoi andare a
http://rampages.onramp.net/~huston/dp/state.html
per una descrizione breve
e a
http://www.mk.dmu.ac.uk/~gperkins/Smalltalk/State/
per una descrizione piu' completa (anche se applicata a Smalltalk).
MM

> Uno studente non e` una persona! Sorpreso?
No, lo sapevo già (e tra l'altro me l'avevano detto anche a scuola).
Conosco questa teoria, che tra l'altro si applica a moltissimi casi
(studente, lavoratore, sposato, celibe, essere in vita!)
Certo che se consideri l'oggetto "Monti Alessandro" come appartenente alla
classe degli "esseri viventi", rischi che la tua analisi del problema
diventi obsoleta prima di 100 anni :)
Però, se stai facendo un programma per una scuola, forse considerare
Studenti "is a" Persona, può andare bene.
Perchè complicarsi la vita quando non è necessario? In ogni progetto sw ci
sono approssimazioni, assunzioni (valide o meno, e per un tempo limitato),
compromessi.
Poichè stavo facendo un esempio, ritenevo che bastasse il concetto
intuitivo, ma se preferisci:
Studente is a property of Persona
Persona is a Uomo
Studente has a Zaino
Vogliamo anche dire che non necessariamente uno studente ha uno zaino?...
Comunque l'obiezione era fondata, lo riconosco.
Ciao
--
Alessandro Monti

 Studente is a property of Persona
Grazie a chi mi ha indirizzato verso il corretto design pattern ora
posso dire che
Studente is a state of Persona
dove state è un membro di Persona ed è un puntatore ad una classe base
di una serie di classi derivate ognuna delle quali rappresenta un
possibile stato della Persona con tutti i suoi specifici comportamenti.
E' possibile cambiare stato semplicemente cambiando il valore di state
facendolo puntare ad un'altra delle classi derivate di cui sopra.
EMG

 Studente is a state of Persona
Va bene, a questo punto mi sembra solo una questione di terminologia, e
confesso la mia ignoranza. Il concetto era lo stesso, ovviamente la
"property" che intendevo io era un puntatore ad oggetto (se necessario).
Dato che ho trovato gente esperta in quest'aspetto della programmazione ad
oggetti, ne approfitto per porre una questione, sperando in un suggerimento
o nuove idee. Ovviamente in un nuovo thread.
--
Alessandro Monti

Studente is a property of Persona
meglio modellarlo come possibile condizione di una persona.
