mercoledì, gennaio 10, 2007

un funtore

Ecco un esempio di funtore banale.
Essendo banale, e' stato implementato inline, cioe' con tutto il codice scritto dentro funtore.h. E' chiaro che:


  • il nome della classe e' arbitrario, non necessariamente funtore
  • l'operator() puo' prendere in ingresso quanti e quali argomenti si voglia e restituire un qualunque oggetto, come un qualunque metodo della classe
  • per funzioni piu' complicate potrebbero essere necessari costruttori e distruttori, l'operator() piu' sofisticato etc, quindi diventa conveniente scrivere l'implementazione nel .cc
  • si faccia attenzione al fatto che operator() e' il nome dell'operatore, quindi poi ci vogliono altre due parentesi tonde con gli argomenti


#ifndef funtore_H
#define funtore_H

#include <iostream>

class funtore
{
public:

funtore () {} ;
~funtore () {} ;

void operator() () {std::cout << "fatto! gia fatto??" << std::endl ;}

private:

};

#endif


Il funtore si utilizza dentro al codice di test creandolo come un oggetto (perche' e' un oggetto) ed usando l'operator() come una funzione, come si vede dall'esempio.
In questo caso e' un operatore banale, che non ritorna nulla, tuttavia si utilizza come una funzione.
Come oggetto, un funtore puo' essere definito, ne si possono definire puntatori, si puo' mettere in vettori e mappe, puo' essere restituito da una funzione, puo' essere passato come argomento ad una funzione (i metodi sono funzioni).

#include "funtore.h"

int main ()
{
// creazione dell'oggetto funtore
funtore oggettoDiTest ;

// utilizzo dell'oggetto di test
oggettoDiTest () ;

return 0 ;

}

mercoledì, gennaio 03, 2007

Inserire oggetti in una mappa

Per inserire un oggetto in una std::map ci sono due metodi possibili.
Uno dei due, che abbiamo gia' visto, si basa sull'implementazione dell'operator[]() per la classe std::map :


std::map<std::string,istogramma> mappaHistos ;
istogramma primoHisto ; // chiamata al default ctor
mappaHistos["primo istogramma"] = primoHisto ;


Un altro metodo per inserire oggetti nella mappa sfrutta il metodo insert della classe std::map:


std::map<std::string,istogramma> mappaHistos ;
istogramma primoHisto ; // chiamata al default ctor
mappaHisto.insert (std::map<std::string,istogramma>::value_type ("primo istogramma",primoHisto)) ;


Si tratta di un modo per inserire nella mappa direttamente un suo elemento, cioe' una coppia (chiave,oggetto) gia' composta.
Innanzitutto, viene creata la coppia, utilizzando value_type, che e' un typedef presente in tutti gli standard container ed e' il tipo contenuto: in questo caso, una coppia (pair).
Per creare la coppia, vengono chiamati i costruttori dei suoi due elementi, vale a dire della stringa e dell'istogramma. Per la stringa a partire da un parametro iniziale, per l'istogramma a partire da primoHisto.
Quando la coppia e' stata creata, viene passata al metodo insert della std::map che provvede ad aggiungere alla mappa un elemento sulla base dell'oggetto temporaneo passatogli come argomento.
Quest'ultimo oggetto temporaneo verra' poi distrutto.

In definitiva, per scrivere tutto un una riga in entrambi i casi:


std::map<std::string,istogramma> mappaHistos ;
mappaHisto.insert (std::map<std::string,istogramma>::value_type ("primo istogramma",istogramma ())) ;
mappaHistos["secondo istogramma"] = primoHisto ;


Ovviamente, al posto del costruttore di default istogramma () ogni costruttore dell'istogramma (NON il copy ctor) puo' essere utilizzato.
Perche' la mappa venga riempita correttamente, e' necessario che il copy constructor e l'operatore di assegnazione operator= () siano implementati.

venerdì, dicembre 15, 2006

giovedì, dicembre 14, 2006

standard template library

giovedì, dicembre 07, 2006

templates

venerdì, dicembre 01, 2006

un vettore dinamico "sicuro" bis

Ecco una possibile implementazione di un vettore dinamico "sicuro", cioe' che maschera il delete incorporandolo nel proprio distruttore.
L'accesso agli elementi del vettore avviene tramite l'operatore overladed operator[]

#ifndef vettore_h
#define vettore_h

/** \class vettore
\brief un vettore dinamico sicuro
*/


template <class T>
class vettore
{
public :
//! costruttore
vettore (const int & elementsNum) :
m_elementsNum (elementsNum) ,
m_elements (new T [m_elementsNum])
{}
//! distruttore
~vettore ()
{
delete [] m_elements ;
}

//! ritorna un elemento
T &
operator[] (const int & i)
{
if (i<m_elementsNum) return m_elements[i] ;
else return m_elements[m_elementsNum-1] ;
}

private :

int m_elementsNum ;
T * m_elements ;

} ;


#endif

un vettore dinamico "sicuro"

Ecco una possibile implementazione di un vettore dinamico "sicuro", cioe' che maschera il delete incorporandolo nel proprio distruttore.

#ifndef vettoreSimple_h
#define vettoreSimple_h

/** \class vettoreSimple
\brief un vettoreSimple dinamico sicuro
*/


template <class T>
class vettoreSimple
{
public :
//! costruttore
vettoreSimple (const int & elementsNum) :
m_elementsNum (elementsNum) ,
m_elements (new T [m_elementsNum])
{}
//! distruttore
~vettoreSimple ()
{
delete [] m_elements ;
}

//! ritorna un elemento (modificabile)
T &
elemento (const int & i)
{
if (i<m_elementsNum) return m_elements[i] ;
else return m_elements[m_elementsNum-1] ;
}

private :

int m_elementsNum ;
T * m_elements ;
} ;


#endif