Newsgroup: it.comp.programmare
Titolo: Problema su gestione informazioni-proprietà di oggetti

Innanzitutto un saluto a tutto il newsgroup,
scrivo per chiedere chiarimenti su un dubbio che ho, devo scrivere un
codice che deve effettuare controlli su vari oggetti di classi
differenti e sulla base di tali controlli compiere azioni e altri
controlli ancora. Vorrei scrivere il codice in c++, ma di fatto non ho
nessun vincolo sulla scelta del linguaggio. Dico innanzitutto che sono
abbastanza ignorante in materia e mi scuso per la scarsa padronanza
del linguaggio.
Vorrei fare un esempio veloce per piegare il problema, ho la seguente
classe:
class Arancio {
void sbuccia();
void dividispicchi();
? bool c'èilverme();
? bool èpresenteilverme
}
Ora spiego i punti interrogativi. Ho un arancio, dopo averlo sbucciato
e divisi i spicchi posso controllare la presenza del verme, se è
presente o meno il verme farò azioni differenti.
La mia domanda è se la presenza del verme è una proprietà
dell'oggetto?.
Di fatto un arancio ha o non ha il verme, è un qualcosa intimanente
legato all'oggetto arancio, ma non posso saperlo se prima non ho
compiuto le operazioni sbuccia e dividispicchi, quindi se ho una
variabile membro  (bool èpresenteilverme) questa sarà indefinita fino
a quando non ho compiuto le operazioni adatte.
Mi chiedo allora se lo stato di un oggetto può avere propietà
indefinite, questo mi preoccupa in quanto io devo trattare con tanti
aranci e non vorrei leggere la variabile membro èpresenteilverme
quando ancora non ho compiuto i controlli.
Ho pensato di non utilizzare un valore booleano, ma ad es un int: -1 è
presente il verme, +1 non è presente il verme, 0 indefinito, ma ogni
volta che leggo questa variabile devo poi fare un controllo sul suo
valore per vedere e non è zero, non esiste una soluzione più elegante?
Sono sicuro che è un dubbio sciocco per chi programma, ma mi sta
facendo pensare da un po' e non trovo una soluzione adatta.
Aspetto fiducioso una vostra risposta.
Ciao a tutti

 a quando non ho compiuto le operazioni adatte.
stai confondendo un  oggetto arancia col suo stato (che dovrebbe essere 
definito e  comunque noto all'  oggetto  stesso)  e quello che sa di 
quell'    oggetto  arancia  un qualsiasi altro oggetto  che ci debba 
interagire. Sono due cose diverse.
La tua variabile bool non può  essere indefinita per una data  arancia 
particolare.  Il verme o c' è  o non c'è. Se  anche assegni alla 
variabile booleana n valore a  caso mediante generatore random l' 
arancia sa benissimo se la proprietà "avere un verme"  è  vera o falsa. 
  (A parte il fatto  che vermi nelle arance non li ho mai trovati...).
Giorgio

 
Devi definire oggetti diversi.
L'oggetto Arancio.
L'oggetto Arancio_sbucciato.
L'oggetto Arancio_diviso_in_spicchi.
Il metodo Arancio.sbuccia() ti ritornera' un oggetto Arancio_sbucciato.
Il metodo Arancio.Dividi_in_spicchi() ti ritornera' un oggetto 
Arancio_diviso_in_spicchi.
Uno di questi oggetti avra' la proprieta' verme a True o a False
Eventualmente puoi pensare di far discendere Arancio_sbucciato da 
Arancio in modo da ereditare tutto quello che ti serve, aggiungere 
metodi e proprieta' nuove ed escludere metodi e proprieta' non piu' utili.

a quando non ho compiuto le operazioni adatte.
Condivido anch'io la perplessità sul fatto che un'arancia (l'arancio è
l'albero) abbia il verme. Piuttosto l'ho visto nelle mele :-)
Comunque, secondo me dovresti vincolare il tutto allo stato del tuo
oggetto:
#include <iostream>
#include <exception>
#include <stdexcept>
typedef enum { sana, sbucciata, divisa } StatoArancia;
class Arancia {
public:
  Arancia(bool verme);
  void sbuccia();
  void dividiInSpicchi();
  bool haVerme();
private:
  bool verme;
  StatoArancia stato;
};
Arancia::Arancia(bool verme) {
    this->stato = sana;
    this->verme = verme;
}
void Arancia::sbuccia() {
    if (this->stato != sana)
      throw std::runtime_error("impossibile sbucciare l'arancia: non
e' sana");
    this->stato = sbucciata;
}
void Arancia::dividiInSpicchi() {
    if (this->stato != sbucciata)
      throw std::runtime_error("impossibile dividere in spicchi
l'arancia: non e' sbucciata");
    this->stato = divisa;
}
bool Arancia::haVerme() {
    if (this->stato != divisa)
      throw std::runtime_error("impossibile trovare il verme: non e'
divisa in spicchi");
    return this->verme;
}
int main()
{
    Arancia a(false);
    try {
       a.sbuccia();
       a.dividiInSpicchi();
       std::cout << "l'arancia ";
       if (!a.haVerme()) std::cout << "non ";
       std::cout << "ha il verme" << std::endl;
    }
    catch (std::exception& e) {
       std::cout << "errore: " << e.what() << std::endl;
    }
}

 oggetto:
Propongo la mia versione (in Python). Forse e' un po' troppo pragmatica? :-)
SANA, SBUCCIATA, DIVISA = range(3)
class Arancia(object):
     def __init__(self, verme):
         self.stato = SANA
         self._verme = verme
     def sbuccia(self):
         if self.stato in (SANA, SBUCCIATA):
             self.stato = SBUCCIATA
         else:
             raise RuntimeError("Impossibile sbucciare l'arancia: e' 
gia' aperta")
     def dividi(self):
         if self.stato in (SBUCCIATA, DIVISA):
             self.stato = DIVISA
         else:
             raise RuntimeError("Impossibile dividere l'arancia: non e' 
sbucciata")
     @property
     def verme(self):
         self.sbuccia()
         self.dividi()
         return self._verme