Oggetti e classi
Eccoci arrivati a quella che è stata la grande introduzione del C++: la Programmazione ad oggetti!
Per programmare ad oggetti bisogna pensare che tutta la realtà sia formata da essi. Vi chiederete cosa è un oggetto???, la risposta è semplice tutto è un oggetto!
Il discorso può sembrare assurdo ma un oggetto non è altro che un elemento dotato di attributi e metodi o in parole povere di variabili e funzioni, la cosa importante da dire è che tali attributi sono nascosti, o meglio incapsulati nei metodi, in modo tale da nascondere agli utenti le proprie caratteristiche le quali sono accessibili solo mediante le funzioni.
Questa caratteristica è molto importante poichè ci permette di riusare oggetti creati da altre persone ed inserirli in un nostro progetto usando solo i metodi lì definiti, senza conoscere come tali metodi agiscano sull'oggetto. Logicamente il discorso vale anche all'inverso, noi possiamo fornire oggetti a terzi.
In C++ un oggetto viene realizzato mediante il costrutto class il quale funziona come le strutture viste nella guida al C. Nell'esempio che segue creeremo una semplice classe per spiegarne le varie funzionalità.
//questo prog acquisisce due numeri
//e stampa il relativo numero complesso
#include <iostream>
#include <iomanip>
using namespace std;
//definizione della classe NumeroComplesso
class NumeroComplesso{
//parte public accessibile a tutti
public:
//costruttore
NumeroComplesso();
//stampa numero complesso
void stampaComplesso();
// acquisisce un numero complesso
void setComplesso ();
//parte accessibile solo tramite le
//funzioni dichiarate public
private:
int parteReale;
int parteComplessa;
};//non dimenticate il ;
//definizione del costruttore
NumeroComplesso::NumeroComplesso()
{
parteReale=parteComplessa=0;
}
//definizione funzione stampaComplesso
void NumeroComplesso::stampaComplesso()
{
cout << parteReale ;
if (parteComplessa < 0)
cout << "-j" << parteComplessa*-1 << endl;
else
cout << "+j" << parteComplessa << endl;
}
//definizione funzione di acquisizione
void NumeroComplesso::setComplesso()
{
int reale,immaginaria;
cout << "Immetti il coefficiente reale:";
cin >> reale;
cout << "Immetti il coefficiente immaginario:";
cin >> immaginaria;
//associazione dei valori immessi
//in input alle variabili private
parteReale=reale;
parteComplessa=immaginaria;
}
int main()
{
/*istanziazione di un oggetto
di tipo numero complesso*/
NumeroComplesso c;
cout << "Il valore iniziale del numero complesso e':";
//chiamata alla funzione stampa complesso
//mediante l'operatore .
c.stampaComplesso();
cout << "Immetti i seguenti valori:" << endl;
//setta il numero complesso
c.setComplesso();
cout << "Il numero complesso immesso e':";
c.stampaComplesso();
cout << endl << endl;
system("PAUSE");
return 0;
}
Analizziamo a fondo tale codice:
class NumeroComplesso{...};
class indica che ciò che segue è una classe, NumeroComplesso è il nome con cui bisognerà istanziare una classe e con cui bisognerà riferirsi alla classe all'interno della sua definizione. All'interno delle parentesi andranno inseriti gli attributi e i metodi della classe. Nota: non dimenticate mai il ; dopo la parentesi graffa potreste impazzire alla ricerca di tale errore.
public
a seguito di tale identificativo vi è la dichiarazione di tutto ciò a cui può accedere il normale utente utilizzando l'operatore '.', praticamente ciò che viene scritto in public corrisponde a quello che era scritto all'interno di una struct.
NumeroComplesso();
è il costruttore della classe. E' obbligatorio inserirlo nella parte public in quanto esso serve quando istanziamo una classe scrivendo NumeroComplesso c; quello qui presente è solo il prototipo, la sua dichiarazione sarà effettuata più avanti.
void stampaComplesso(); e void setComplesso ();
sono i prototipi di due funzioni il cui scopo è abbastanza chiaro. Anch'esse sono nella parte public poichè devono operare su quelli che sono i dati privati della nostra classe.
private
con questo identificativo indichiamo gli attributi o i metodi che intendiamo proteggere dall'esterno e quindi sarà possibile accedere ad essi esclusivamente mediante l'uso di funzioni dichiarate public.
int parteReale; e int parteComplessa;
sono i nostri membri privati quelli a cui non si può accedere dal main scrivendo cose del tipo:
-
Numero complesso c;
c.parteReale = 2;
c.parteComplessa = -3;
Nota: spesso vengo utilizzati come nomi di metodi public le parole set e get le quali indicano, rispettivamente, il settaggio e il prelievo di info contenute in variabili private.
Segue ora la definizione dei metodi; notiamo subito che tutti i metodi devono essere dichiarati nella seguente forma:
-
tipoRitorno NomeClasse::nomeFunzione(eventuali argomenti)
Esaminiamo solo il codice della funzione setComplesso in quanto nelle definizioni delle funzioni non vi sono novità... tutto funziona come al solito:
void NumeroComplesso::setComplesso()
significa che segue la definizione del metodo setComplesso che non restituisce nulla, privo di parametri di scambio appartenente alla classe NumeroComplesso. Il codice segue effettuando una richiesta di immissione della parte reale e di quella immaginaria, memorizzate in variabili d'appoggio temporanee i quali valori poi verranno assegnati alle variabili private (parteReale e parteComplessa) a cui ora possiamo accedere in quanto siamo noi i proprietari della classe.
Il codice continua con il main in cui viene istanziato un oggetto c di tipo NumeroComplesso e viene visualizzatto il suo valore iniziale con la chiamata alla funzione stampaComplesso effettuata secondo la forma c.stampaComplesso(); a questo punto viene richiesto di inserire un nuovo numero complesso con la chiamata c.getComplesso() a cui segue una nuova stampa.
Vi chiederete qual è stata l'utilità di creare una classe NumeroComplesso, la risposta è semplice: in C non esiste un tipo predefinito in grado di utilizzare gli oggetti quindi in questa guida creeremo man mano tutto ciò di cui abbiamo bisogno per gestire il tipo complesso compresi gli operatori di somma differenza etc etc.







