Corso di Programmazione ad Oggetti

Похожие документы
Definizione di classi. Walter Didimo

Laboratorio di programmazione

Gestione dinamica della memoria

Il paradigma OO e le Classi

La programmazione ad oggetti (OOP)

Allocazione Dinamica della Memoria

Informatica 1 Tipi e dichiarazioni in C++ C++ - Tipi e dichiarazioni 1

14 - Metodi e Costruttori

La gestione della memoria dinamica Heap

Programmazione con Java

La Gestione della Memoria. Carla Binucci e Walter Didimo

9 - Array. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Ogni variabile in C è una astrazione di una cella di memoria a cui corrisponde un nome, un contenuto e un indirizzo.

Funzioni, Stack e Visibilità delle Variabili in C

Linguaggio C: PUNTATORI

Il linguaggio C. Puntatori e dintorni

C: panoramica. Violetta Lonati

INTRODUZIONE ALLA PROGRAMMAZIONE AD ALTO LIVELLO IL LINGUAGGIO JAVA. Fondamenti di Informatica - D. Talia - UNICAL 1. Fondamenti di Informatica

Unità Didattica 4 Linguaggio C. Vettori. Puntatori. Funzioni: passaggio di parametri per indirizzo.

Definizione di metodi in Java

7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari

Programmazione a oggetti

Parametri Formali di una Funzione e Record di Attivazione

Funzioni in C. Funzioni. Strategie di programmazione. Funzioni in C. Come riusare il codice? (2/3) Come riusare il codice? (1/3)

Introduzione al linguaggio C Puntatori

Tipi di dati strutturati e Linguaggio C. Record o strutture Il costruttore struct in C

Allocazione statica della memoria

Esempio su strutture dati dinamiche: ArrayList

Esercizi riassuntivi (Fondamenti di Informatica 2 Walter Didimo) Soluzioni

Programmazione a Oggetti Lezione 7. Il linguaggio Java: aspetti generali

Esercizi sulla macchina assembler, strutturazione a livelli, spazio di indirizzamento

L'Allocazione Dinamica della Memoria nel linguaggio C

Corso di Fondamenti di Informatica Il sistema dei tipi in C++

Il linguaggio C. Notate che...

I/O FILE. Sommario I/O FILE. I/O FILE LETTURA DA FILE DI TESTO oggetto di tipo ifstream. I/O FILE: lettura e scrittura su file di testo

La classe std::vector della Standard Template Library del C++

Strutture Dati Dinamiche

Perché il linguaggio C?

Esempio su strutture dati dinamiche: ArrayList

Uso avanzato dei puntatori Allocazione dinamica della memoria

Sommario. Le differenze fra C e C++ Funzioni. Varie. Memoria. commenti. parametri per funzioni funzioni inline overloading di funzione

Gli Array. Dichiarazione di un array

STRINGHE IN JAVA In Java, le stringhe non sono pezzi di memo-ria con dentro dei caratteri, come in C: sono oggetti appartenenti alla classe

Esercizio 2: Algebra dei Puntatori e Puntatori a Puntatori

Unità Didattica 3 Linguaggio C. Generalità sulle Funzioni. Variabili locali e globali. Passaggio di parametri per valore.

Транскрипт:

Corso di Programmazione ad Oggetti Costruttori di copia, funzioni di accesso e variabili static aa 2008/2009 Claudio De Stefano Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 1

Richiami sui Costruttori Un costruttore è una particolare funzione membro di una classe che porta lo stesso nome della classe Per le funzioni costruttore non deve essere specificato il tipo restituito, in quanto in C++ le funzioni costruttore non possono restituire valore I costruttori possono avere anche uno o più parametri Esempio class Contatore public: Contatore(); ; Contatore::Contatore() value = 0; Contatore::Contatore(int val) value = val; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 2

Richiami sui Costruttori Il costruttore di un oggetto viene chiamato automaticamente nel momento in cui deve essere creato l'oggetto Esempi #include Contatoreh Contatore cont1, cont2(100); Contatore cont_ptr1, cont_ptr2; cont_ptr1 = new Contatore; cont_ptr2 = new Contatore(10); Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 3

Richiami sui Distruttori Un distruttore è una funzione membro che: è necessaria solo se l oggetto presenta un estensione dinamica ha lo stesso nome della classe, preceduto da ~ (tilde) non restituisce risultato (neanche void) non ha alcun parametro Generalmente lo scopo dei distruttori è quello di deallocare l estensione dinamica di un oggetto NON può essere invocata esplicitamente dal programma utente, ma viene invocata implicitamente dal compilatore quando viene deallocato lo spazio di memoria assegnato all'oggetto Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 4

Esempio di distruttore Per quanto detto in precedenza, il costruttore serve per deallocare le estensioni dinamiche degli oggetti Esempio Class Stack public: Stack(); ~Stack(); private: int *st_ptr; int num; ; // Costruttore Stack::Stack() st_ptr = new int[size]; num = 0; // Distruttore Stack::~Stack() delete [] st_ptr; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 5

Esecuzione dei distruttori I distruttori vengono eseguiti anche quando vengono deallocati oggetti precedentemente allocati dinamicamente Esempio void funz() Stack *st_ptr; delete st_ptr; Viene invocato il distruttore di stack Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 6

Il costruttore di copia Crea un oggetto a partire da un altro oggetto della classe (i valori delle variabili membro vengono copiati) La sintassi dei costruttori di copia è la seguente: class Myclass Myclass(const Myclass &oggetto); ; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 7

Chiamata dei costruttori di copia I costruttori di copia sono chiamati in maniera implicita: All atto della definizione di un oggetto per inizializzarlo con il valore di un altro oggetto: Myclass m2=m1; oppure Myclass m2(m1); All atto della chiamata di una funzione per inizializzare un argomento (oggetto) passato per valore All atto del ritorno da una funzione, per restituire un oggetto per valore La definzione di un costruttore di copia consente di risolvere tutti i problemi visti in precedenza relativi alla copia di oggetti che hanno un'estensione Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 8

Confronto tra costruttori di copia In mancanza della definizione del costruttore di copia, il compilatore richiama un costruttore di copia di default Il costruttore di copia di default esegue una copia copia bit a bit, limitata alla sola parte base Nel caso esista una estensione dinamica il costruttore di copia deve essere esplicitamente definito dal progettista della classe Costrutture di copia di default (bit a bit) Costrutture di copia di ad hoc obj Estensione di obj obj Estensione di obj Copia di obj Copia di obj Copia dell'estensione Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 9

Un esempio: la classe stack Poniamo di avere la seguente classe: Class Stack public: Stack(); Stack(int dim); ~Stack(); Stack(const &Stack) private: int *st_ptr; int num; int size: ; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 10

la classe stack // Costruttore 1: alloca un array con una dimensione di default Stack::Stack() st_ptr = new int[stack_size]; num = 0; size = STACK_SIZE; // Costruttore 2: alloca un array di dimensione dim Stack::Stack(int dim) st_ptr = new int[dim]; num = 0; size = dim; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 11

la classe stack // Costruttore di copia Stack::Stack(const Stack &s) int i; num = snum; dim = sdim; s_ptr = new int[dim]; for (i=0; i < num; ++i) s_ptr[i] = ss_ptr[i]; // Distruttore Stack::~Stack() delete [] st_ptr; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 12

Variabili static Le variabili di una classe possono essere dichiarati static Quando la dichiarazione di una variabile membro è preceduta dalla parola static, si chiede al compilatore di creare una sola copia di quella variabile per tutti gli oggetti della classe Questo significa che tutti gli oggetti di quella classe utilizzeranno la stessa variabile (per individuarla si usa il nome della classe con l'operatore :: ); in questo modo è possibile condividere la stessa informazione tra più oggetti della stessa classe Quando si dichiarano variabili static non si alloca spazio di memoria all'interno degli oggetti della classe per tali variabili L'utilità delle variabili static deriva dal fatto che in questo modo è possibile condividere la stessa informazione tra più oggetti della stessa classe Tutte le variabili static vengono inizializzate a zero nel momento in cui viene creato il primo oggetto Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 13

Variabili static Le variabili static non vengono create tramite istanze della classe a cui appartengono, ma devono essere definite all esterno della classe ma nello stesso ambito in cui è definita la classe Nei rari casi, però, in cui la classe è definita in un block scope, le variabili static non sono ammesse Pertanto una variabile static può essere definita solo in un namespace (se la classe è definita in quel namespace) o nel namespace globale Le variabili static possono essere private o pubbliche; se una variabile di classe static è privata, tale variabile potrà essere gestita solo da un metodo della classe a cui appartiene Le variabili static sono molto utili per gestire informazioni comuni a tutti gli oggetti di una classe (per esempio possono fornire i dati di default per l'inizializzazione degli oggetti), ma nel contempo, essendo esse stesse membri della classe, permettono di evitare il ricorso a variabili esterne, salvaguardando così il data hiding e l'indipendenza del codice di implementazione della classe dalle altre parti del programma Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 14

Variabili static: esempio 1 Le variabili di tipo static possono essere usate per contare il numero di oggetti istanziati di un certa classe: class Counter public: static int count; Counter()++count;; ~Counter()--count;; ; int Counter::Count; main() Counter count_array[100]; cout<<endl<< oggetti esistenti: <<Counter::count; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 15

Variabili static: esempio 2 class ShareVar static int num; public: void setnum(int i) num = i; ; void shownum() cout << num << " "; ; int ShareVar::num; // definisce num int main() ShareVar a, b; ashownum(); // visualizza 0 bshownum(); // visualizza 0 asetnum(10); // imposta static num a 10 ashownum(); // visualizza 10 bshownum(); // anche questa istruzione visualizza 10 return 0; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 16

Variabili static: esempio 3 Le variabili di tipo static possono essere usate per condividere risorse comuni a tutti gli oggetti di una classe: class Myclass static int resource; public: Myclass(); bool get_resource(); void free_resource() resource = 0; ; void shownum() cout << num << " "; ; bool cl::get_resource() if (resource == 0) resource = 1; return true; else return false; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 17

Variabili static: esempio 3 main() Myclass m1, m2; if (m1get_resource()) cout<< la risorsa è di m1 ; if (!m2get_resource()) cout<< m2 non può utilizzare la risorsa ; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 18

Funzioni membro di tipo static Anche le funzioni membro possono essere di tipo static Le funzioni definite static possono accedere solo alle variabili static della classe Non hanno inoltre il puntatore this; L'uso di queste funzioni è piuttosto limitato Vengono di solito usate per inizializzare le variabili static di una classe class A static int conta( ) ; ; (prototipo) int A::conta( ) (definizione) Nel prog chiamante: int n = A::conta( ); Nella chiamata di una funzione-membro static, bisogna qualificare il suo nome con quello della classe di appartenenza Si noti che, nella definizione della funzione, lo specificatore static non va messo (per lo stesso motivo per cui non va messo davanti alla definizione di un dato-membro static) Se una funzione-membro static deve operare su un oggetto, questo deve essere trasmesso esplicitamente come argomento quando un metodo deve operare direttamente su un oggetto (uno e uno solo alla volta), è più conveniente che sia incapsulato nell'oggetto stesso e quindi non venga dichiarato static Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 19

Funzioni di accesso alle variabili membro: lettura Sappiamo che lo stato di un oggetto è determinato dal valore delle variabili da esso contenuto È buona norma della programmazione OO definire tali variabili private Per consentire agli utenti di una classe di visualizzare lo stato di un oggetto istanziato è necessario quindi definire delle funzioni che consentono di accedere alle sue variabili Una tipica definizione di funzione di accesso è del tipo: Tipo get_value()return value; Tipicamente queste funzioni sono definite all'interno della dichiarazione della classe Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 20

Funzioni di accesso alle variabili membro: modifica Oltre che leggere lo stato di un oggetto è anche necessario modificarlo Pertanto bisogna definire anche delle funzioni che consentono la modifica delle variabili di un oggetto Una tipica definizione di funzione di modifica è del tipo: void set_value(tipo val)var = val; NOTA La scelta di nomi del tipo get_nomevar e set_nomevar è una buona norma di programmazione, ma non è assolutamente prescritta dal linguaggio C++ Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 21

Esempio Class Myclass public: // Funzioni Costruttore Myclass(); // Funzioni di accesso int get_n()return N;; //restituisce il valore di N char get_ch()return ch;; //restituisce il valore di ch void set_n(int val)n = val;; // assegna valore a N void set_ch(char c)char = c;; // assegna valore a ch private: int N; char ch; float x; ; Le funzioni membro definite nella dichiarazione de vengono automaticamente trasformate in funzioni inline dal compilatore Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 22

L'accesso ai membri di una classe Quando definiamo una funzione membro di una classe, possiamo fare riferimento alle variabili membro della classe senza ambiguità Class Myclass public: Myclass(); funz(tipo val); private: Tipo1 var1; Tipo1 var2; ; Myclass::funz(Tipo val) var2 = pow(x, 2); main() Myclass m1, m2; m1funz(); // modifica le variabili di m1 m2funz(); // modifica le variabili di m2 Domanda ma qual'è il meccanismo che consente alla funzione membro di individuare le variabili specifiche dell'oggetto sul quale è stata chiamata? Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 23

Meccanismo di accesso ai membri di una classe Nella chiamata di una funzione membro il compilatore introduce un primo parametro nascosto che è l indirizzo dell oggetto proprio a cui f viene applicata Tale parametro e un puntatore costante il cui nome è this Myclassh Class Myclass Tipo funz(tipo val); ; Viene trasformata dal compilatore in Class Myclass Tipo funz(myclass* const this, Tipo val); ; Myclassh modificato Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 24

Il puntatore This Il ruolo del puntatore this è quello di identificare l'oggetto istanziato al quale applicare una certa funzione della classe Infatti quando si definisce una funzione membro non si specifica in alcun modo l'oggetto sul quale la funzione verrà chiamata Questa operazione viene fatta in maniera automatica dal compilatore Il quale, modifica i riferimenti alle variabili di classe aggiungendo il puntatore this Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 25

Esempio Ovviamente la traformazione interessa anche il file cpp: Tipo Myclass::funz(Tipo1 val) var1 = pow(2, val); ; Myclasscpp Compilatore Myclasscpp modificato Tipo Myclass::funz(Myclass* const this, Tipo1 val) this->var1 = pow(2, val); ; Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 26

Chiamata delle funzioni membro L'istruzione di chiamata di una funzione membro su una specifica istanza di una classe viene anch'essa trasformata dal compilatore In pratica l'indirizzo dell'oggetto (tramite l'operatore &) viene ricopiato in this e attraverso tale puntatore la funzione opera sull oggetto proprio: main () Myclass m, *mp; Tipo1 x; mfunz(x); mp->funz(x); compilatore main () Myclass m; Tipo1 x; funz(&m, x); funz(mp, x); Claudio De Stefano - Corso di Programmazione ad Oggetti - aa 2008/2009 27