Newsgroup: it.comp.lang.c++
Titolo: Ereditare per usare funzionalita´

Salve a tutti,
ho un problema quando devo decidere se usare l´ereditarieta´ o no.
Fino ad ora avevo capito che l´ereditarieta´ e´ quando si ha una relazione
"kind of" mentre l´incapsulazione e´ una relazione "has-a". (Come descritto
nel libro "C++ Faqs" di Cline, Lomow, Girou).
Quindi banalmente puo´ essere facile capire che la classe camion puo´
ereditare dalla classe base veicolo.
Pero´ leggendo il libro di Scott Meyers "Effective C++" sono incappato
nell´implementazione di un template che supporta la gestione dell´operatore
new gestendone le eccezioni, il quale puo´ essere ereditato da una qualsiasi
classe che voglia usare questa funzionalita´.
Allora a questo punto io potrei costruire una classe con certe funzionalita´
generiche e poi farla ereditare da altre classi che non hanno niente in
comune con questa solo per fare in modo che esse sfruttino le sue
funzionalita´?
Vi copio l´esempio di Meyers con il template NewHandlerSupport che
ridefinisce l´operatore new e con la classe X generica che eredita
pubblicamente da NewHandlerSupport.
template<class T>    // "mixin-style" base class
class NewHandlerSupport
{   // for class-specific
public:      // set_new_handler support
  static new_handler set_new_handler(new_handler p);
  static void * operator new(size_t size);
private:
  static new_handler currentHandler;
};
template<class T>
new_handler NewHandlerSupport<T>::set_new_handler(new_handler p)
{
  new_handler oldHandler = currentHandler;
  currentHandler = p;
  return oldHandler;
}
template<class T>
void * NewHandlerSupport<T>::operator new(size_t size)
{
  new_handler globalHandler =
    std::set_new_handler(currentHandler);
  void *memory;
  try {
    memory = ::operator new(size);
  }
  catch (std::bad_alloc&) {
    std::set_new_handler(globalHandler);
    throw;
  }
  std::set_new_handler(globalHandler);
  return memory;
}
// this sets each currentHandler to 0
template<class T>
new_handler NewHandlerSupport<T>::currentHandler;
// With this class template, adding set_new_handler support
// class X is easy: X just inherits from newHandlerSupport<X>
// note inheritance from mixin base class template. (See
// my article on counting objects for information on why
// private inheritance might be preferable here.)
class X: public NewHandlerSupport<X>
{
  ...                 // as before, but no declarations for
};                    // set_new_handler or operator new
Vi ringrazio se mi illuminate sul mio dubbio
Mauro


Si tratta di classi mix-in (in genere vengono usate da chi non e'
contrario all'ereditarieta' multipla ;-)
Anche in questo caso si tratta di una relazione "is a".
NewHandlerSupport<T> e' una classe che implementa una certa proprieta',
per esempio  "e' una classe che gestisce il new handler".
Qualsiasi classe derivata da questa e' anch'essa "una classe che
gestisce il new handler".
I 'fan' delle classi mixin di solito dividono tutte le proprieta' che
possono avere gli oggetti di cui hanno bisogno e poi derivano questi
dalle classi che servono.
Ad esempio puoi avere una serie di classi :
HaUnMotore, HaLeRuote, HaLeAli, Vola, Cammina ...
e finalmente:
class Aereo : public HaUnMotore,
              public HaLeAli,
              public Vola {...};
class Aliante : public HaLeAli,
                public Vola {...};
class Automobile : public HaUnMotore,
                   public HaLeRuote,
                   public Cammina {...};
Il vantaggio di una cosa del genere consiste nel gestire facilmente e
uniformemente queste proprieta'.
Ad esempio puoi avere una classe del genere
class Meccanico
{
  bool controllaMotore(HaUnMotore &obj);
  bool gonfiaRuote(HaLeRuote &obj);
  ...
};
L'esempio e' un po' stupido, ma credo che rendi l'idea...
./fabio
Sent via Deja.com
http://www.deja.com/

funzionalita´?
Certamente.
Le classi concrete, molto spesso, ereditano da classi astratte, le
quali vengono concepite come una semplice interfaccia.
Ereditare significhi proprio offrire una interfaccia al proprio
oggetto.
Se il proprio oggetto deve avere piu' interfacce, allora si eredita da
piu' classi astratte. Un esempio che ho trovato in questi giorni su
"Essential COM" e' quello che spiega, appunto, l'importanza delle
interfacce con questa tecnologia.
Don Box, a pag. 11 in "Separating Interface from Implementation",
afferma :
"The concept of encapsulation is based on separating what an object
looks like (its interface) from how it actually works (its
implementation). [...] By defining one C++ class to represent the
interface to a data type and another C++ class as the data type's
actual implementation, the object implementor can theoretically modify
the implementation class's details while holding the interface class
constant. All that is needed is a way to associate the interface with
its implementation without revealing any implementation details to the
client".
Non e' escluso, quindi, che un oggetto possa subire eredita' multipla,
perche' non e' escluso che abbia interfacce di diverso tipo.
--
Andrea Laforgia (ICQ 87230455)
http://www.geocities.com/AndreaLaforgia
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

oggetto.
veramente da come ho capito io maurus si riferiva al riuso del codice
tramite l'ereditarietà (classe base concreta) e non alle interfaccie
(classe base astratta)
Anto
--
Antonio Cuni, 18 anni, studente
Brainbench Certification: 
Master C++: 4.44, higher than 97% of all previous test takers.
Visual Basic 5: 3.06, higher than 77% of all previous test takers.
http://www.brainbench.com/transcript.jsp?pid=1301688

 };                    // set_new_handler or operator new
Hai letto la nota?
Dice che sarebbe preferibile l'ereditarietą *privata* a quella *pubblica*.
Un motivo c'č. E' che mentre l'ereditarietą pubblica modella una relazione
di tipo is-a (č-un), l'ereditarietą privata modella una relazione del tipo
has-a (ha-un).
Sono in molti a snobbare l'ereditarietą privata in favore di quella
pubblica, commettendo spesso gravi errori.
Ad esempio, chi ha progettato MFC dubito abbia mai sentito parlare di
ereditarietą privata...
Ciao!
Daniele.

(classe base astratta)
Il discorso non e' molto diverso dalle classi astratte.
Il nostro amico si riferiva a funzionalita' generiche e quindi ho
interpretato con classi astratte.
