INF3105 Tableaux dynamiques et génériques

Documents pareils
INFO-F-105 Language de programmation I Séance VI

et Programmation Objet

as Architecture des Systèmes d Information

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Cours d initiation à la programmation en C++ Johann Cuenin

C++ COURS N 2 : CLASSES, DONNÉES ET FONCTIONS MEMBRES Classes et objets en C++ Membres d'une classe Spécification d'une classe Codage du comportement

1.6- Génération de nombres aléatoires

Génie Logiciel avec Ada. 4 février 2013

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

TP, première séquence d exercices.

Une introduction à Java

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Java c est quoi? Java pourquoi?

30.avr.10 Présentation miniprojet. 9.mars.10 Cours 3 4.mai.10 Cours C mars.10 Cours 4 11.mai.10 Cours C++ 2

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Introduction à C++ et à wxwidgets

Cours 1: Java et les objets

Programmer en JAVA. par Tama

Le langage C++ (partie I)

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Généralités sur le Langage Java et éléments syntaxiques.

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

TD/TP PAC - Programmation n 3

Chapitre VI- La validation de la composition.

Java Licence Professionnelle CISII,

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Chapitre 2. Classes et objets

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Programme Compte bancaire (code)

Introduction à l héritage en C++

IRL : Simulation distribuée pour les systèmes embarqués

GOL502 Industries de services

Chapitre 10 Arithmétique réelle

Premiers Pas en Programmation Objet : les Classes et les Objets

TD/TP PAC - Programmation n 3

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Plan Pédagogique du cours

Programmation avec des objets : Cours 7. Menu du jour

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Langage Java. Classe de première SI

Plan du cours. Historique du langage Nouveautés de Java 7

Programmation Orientée Objet Java

Java DataBaseConnectivity

Introduction au langage C

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Package Java.util Classe générique

Héritage presque multiple en Java (1/2)

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Département Automatisation et Informatisation Année Programmation en C++ Institut des Sciences et Techniques de l Ingénieur d Angers

I. Introduction aux fonctions : les fonctions standards

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Cours d Algorithmique et de Langage C v 3.0

Avertissement : Ce cours suppose la connaissance et la maîtrise du langage C CONTENU DU COURS BIBLIOGRAPHIE

Analyse de sécurité de logiciels système par typage statique

Bases de programmation. Cours 5. Structurer les données

Structurer ses données : les tableaux. Introduction à la programmation


Programmation en C/C++

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Introduction au pricing d option en finance

Utilisation d objets : String et ArrayList

Programmation en Java IUT GEII (MC-II1) 1

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Web Tier : déploiement de servlets

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Exercices sur les interfaces

Génie Logiciel I. Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string

TP1 : Initiation à Java et Eclipse

4. Groupement d objets

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

Facultés Universitaires Notre-Dame de la Paix. Conception et Programmation Orientées- Object

Programmation Objet I

Programmation par les Objets en Java

Exercices INF5171 : série #3 (Automne 2012)

Généricité. en Java. (polymorphisme paramétrique) Philippe GENOUD UJF Janvier

TD3: tableaux avancées, première classe et chaînes

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Compression de Données - Algorithme de Huffman Document de Conception

COMPARAISONDESLANGAGESC, C++, JAVA ET

Cours: Administration d'une Base de Données

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

Chapitre 1 : La gestion dynamique de la mémoire

Projet de programmation (IK3) : TP n 1 Correction

INITIATION AU LANGAGE JAVA

Aide mémoire UML & Java 1ère partie : Introduction. marc.lemaire@u-cergy.fr

Algorithmique et Programmation, IMA

1 Définition d une classe en Java

JAVA TD0. Prise en main du langage Environnement de base JAVA 1

Plan global Outils de développement et compilation. Plan. Objectifs des outils présentés. IDE, GCC/Clang, ASAN, perf, valgrind, GDB.

Programmation par composants (1/3) Programmation par composants (2/3)

Programmation Par Objets

Transcription:

INF3105 Tableaux dynamiques et génériques Éric Beaudry Université du Québec à Montréal (UQAM) 2016A Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 1 / 31

Sommaire 1 Tableau natif C++ 2 Tableau dynamique 3 Généricité en C++ (Templates) 4 Tableau abstrait générique 5 Lab3 Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 2 / 31

Allocation automatique La taille doit être connue (déductible) lors de la compilation. La taille doit être fixée dans le code source. Généralement, impossible de spécifier la taille à l exécution. Sur la pile int main(){ int tableau1[10]; int tableau2[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; int tableau3[10] = { 0, 1, 2, 3, 4, 5; Dans un objet class A{ public:... private: int tableau1[10]; double tableau2[10]; ; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 3 / 31

Allocation dynamique La taille peut être inconnue lors de la compilation. Allocation sur le tas (heap) explicite par l opérateur new. La taille demeure fixe après l allocation. Libération de la mémoire par l opérateur delete []. Dans une fonction int main(){ int tableau1 = new int[10]; int tableau2 = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;... delete[] tableau1; delete[] tableau2; Dans un objet class A{ public: A(int n=10) {tableau=new int[n]; ~A(){delete[] tableau; private: int tableau; ; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 4 / 31

Que fait ce programme? #include <iostream> int main() { int tab1[5], tab2[5]; for(int i=0;i<5;i++){ tab1[i] = i; tab2[i] = i + 10; std::cout << "tab1[0..15] :"; for(int i=0;i<16;i++) cout << " " << tab1[i]; std::cout << std::endl; for(int i=0;i<15;i++) tab1[i] = 99 i; std::cout << "tab1 :"; for(int i=0;i<5;i++) std::cout << " " << tab1[i]; std::cout << std::endl; std::cout << "tab2 :"; for(int i=0;i<5;i++) std::cout << " " << tab2[i]; std::cout << std::endl; return 0; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 5 / 31

Limites des tableaux natifs de C++ Taille fixe. Pour contourner le problème de taille fixe, il faut : 1 allouer un nouveau tableau ; 2 copier les éléments de l ancien vers le nouveau ; 3 libérer l ancien tableau. Un tableau est accessible via un pointeur. La taille du tableau est dissociée du pointeur. Non-vérification des indices lors de l accès aux éléments. Conclusion : pas possible de manipuler un tableau comme un objet abstrait. Besoin d une structure de données abstraite de type tableau. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 6 / 31

Objectifs Manipuler des tableaux comme des objets. Faire abstraction des pointeurs et de la gestion de mémoire. Modifier la taille d un tableau (taille dynamique). Vérifier les indices lors de l accès afin de déceler les bogues le plus tôt possible. Comment : Créer un type abstrait de données de type Tableau<T>. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 7 / 31

Utilisation souhaitée Nous aimerions manipuler les tableaux de la même façon que des objets. Exemple : int main(){ TableauInt tab1; tab1.ajouter(1); tab1.ajouter(2); tab1.ajouter(3); int a = tab1[1]; TableauInt tab2 = tab1; // fait une copie de tab1 tab1.ajouter(1); tab1.ajouter(2); tab1.ajouter(3); tab2[1] = 34; assert(a == tab1[1]); // le tableau tab1 doit ne pas etre modifie for(int i=0;i<tab1.taille();i++) cout << tab1[i] << endl; return 0; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 8 / 31

Solution Encapsulation d un tableau natif à l intérieur d un objet Tableau. La classe Tableau encapsule : un pointeur vers un tableau natif ; la capacité du tableau natif ; le nombre d éléments dans le tableau abstrait ( capacité) ; Les accès au tableau passent par une interface publique. Accès indirect au tableau natif. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 9 / 31

La classe TableauInt tableauint.h class TableauInt{ public: TableauInt(); ~TableauInt(); void ajouter(int nombre); int& operator[](int index); private: int entiers; int capacite; int taille; ; tableauint.cpp TableauInt::TableauInt(){ capacite = 4; taille = 0; entiers = new int[capacite]; TableauInt::~TableauInt(){ delete[] entiers; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 10 / 31

Suite tableau.cpp void TableauInt::ajouter(int nombre){ assert(taille<capacite); entiers[taille++]=nombre; int& TableauInt::operator[](int index){ assert(index>=0 && index<taille); return entiers[index]; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 11 / 31

Avec réallocation transparente / automatique void TableauInt::ajouter(int nombre){ if(taille==capacite){ capacite++; // Methode naive : O(n) int nouveautab = new int[capacite]; for(int i=0;i<taille;i++) nouveautab[i] = entiers[i]; delete[] entiers; entiers = nouveautab; entiers[taille++]=nombre; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 12 / 31

Avec réallocation transparente / automatique void TableauInt::ajouter(int nombre){ if(taille==capacite){ capacite = 2; // cout amortie : O(1) int nouveautab = new int[capacite]; for(int i=0;i<taille;i++) nouveautab[i] = entiers[i]; delete[] entiers; entiers = nouveautab; entiers[taille++]=nombre; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 13 / 31

Problématique On peut avoir besoin de plusieurs classes et fonctions similaires, mais légèrement différentes au niveau des types. TableauPoints class TableauPoints{ public:... void ajouter(const Point& p);... private: Point points; int capacite; int nbpoints; ; TableauStrings class TableauStrings{ public:... void ajouter(const String& p);... private: String strings; int capacite; int nbstrings; ; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 14 / 31

Mécanisme de généricité dans C++ Écriture d un modèle générique (un template). Variables de type (nous la noterons souvent T). À chaque instanciation d un modèle : «copier-coller» du modèle ; «recherche-remplacer» pour affecter la variable de type à une type précis. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 15 / 31

Code écrit par le programmeur template <class T> class Point{ T x, y; public: Point(T x_, T y_); ; template <class T> Point::Point(T x_, T y_) : x(x_), y(y_){ int main(){ Point<float> p1; Point<double> p2; Instanciation par le compilateur class Point<float>{ float x, y; public: Point<float>(float x_, float y_); ; Point<float>::Point<float>(float x_, float y_) : x(x_), y(y_){ class Point<double>{ double x, y; public: Point<double>(double x_, double y_); ; Point<double>::Point<double>(double x_, double y_) : x(x_), y(y_){ int main(){ Point<float> p1; Point<double> p2; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 16 / 31

Déclaration template <class T> class Tableau { public: Tableau(int capacite_initiale=4); ~Tableau(); int taille() const {return nbelements; void ajouter(const T& item); T& operator[] (int index); const T& operator[] (int index) const; private: T elements; int capacite; int nbelements; void redimensionner(int nouvcapacite); ; // mettre la suite ici OU dans tableau.hcc qu on inclut ici. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 17 / 31

Représentation abstraite en mémoire elements capacite nbelements 4 0 Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 18 / 31

Constructeur et destructeur template <class T> Tableau<T>::Tableau(int initcapacite) { capacite = initcapacite; nbelements = 0; elements = new T[capacite]; template <class T> Tableau<T>::~Tableau() { delete[] elements; elements = NULL; // optionnel Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 19 / 31

Ajout template <class T> void Tableau<T>::ajouter(const T& item) { if(nbelements >= capacite) redimensionner(capacite 2); elements[nbelements++] = item; template <class T> void Tableau<T>::redimensionner(int nouvcapacite) { capacite = nouvcapacite; T temp = new T[capacite]; for(int i=0;i<nbelements;i++) temp[i] = elements[i]; delete [] elements; elements = temp; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 20 / 31

operator[] template <class T> T& Tableau<T>::operator[] (int index){ assert(index<nbelements); return elements[index]; template <class T> const T& Tableau<T>::operator[] (int index) const{ assert(index<nbelements); return elements[index]; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 21 / 31

operator[] void affiche(const Tableau<int>& tab){ for(int i=0;i<tab.taille();i++) cout << tab[i] << endl; int main(){ Tableau<int> tab; for(int i=0;i<10;i++) tab.ajouter(i); for(int i=0;i<tab.taille();i++) tab[i] = 2; affiche(tab); return 0; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 22 / 31

Affectation (operator=) void fonction(){ Tableau<int> tab1(); tab1.ajouter(1); tab1.ajouter(3); tab1.ajouter(4); tab1.ajouter(5); Tableau<int> tab2(); tab2.ajouter(8); tab2.ajouter(7); tab2.ajouter(3); tab1 = tab2; // cela devrait copier tab2 vers tab1 Que se passe-t-il? L opérateur égal n ayant pas été surchargé, le compilateur en génère un. Ce dernier ne fait qu appeler l opérateur = sur les variables de Tableau. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 23 / 31

Représentation AVANT tab1=tab2. tab2. tab1. Pile d'exécution elements capacite 4 nbelements 4 elements capacite 4 nbelements 3 Heap 1 3 4 5 8 7 3? Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 24 / 31

Code synthétisé par le compilateur pour Tableau : :operator = template <class T> Tableau& operator Tableau<T>::operator=(const Tableau<T>& autre){ elements = autre.elements; capacite = autre.capacite; nbelements = autre.nbelements; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 25 / 31

Représentation APRÈS tab1=tab2. tab2. tab1. Pile d'exécution elements capacite 4 nbelements 3 elements capacite 4 nbelements 3 Heap 1 3 4 5 8 7 3? Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 26 / 31

Bon code pour Tableau : :operator = template <class T> Tableau<T>& Tableau<T>::operator = (const Tableau<T>& autre){ if(this==&autre) return this;//cas special lorsqu on affecte un objet a lui meme nbelements = autre.nbelements; if(capacite<autre.nbelements){ delete[] elements; capacite = autre.nbelements; //ou autre.capacite elements = new T[capacite]; for(int i=0;i<nbelements;i++) elements[i] = autre.elements[i]; return this; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 27 / 31

Constructeur par copie d un tableau int fonction(tableau<int> tab){ // tab par valeur et non pas par reference int sommedouble=0; for(int i=0;i<tab.taille();i++){ tab[i] =2; sommedouble += tab[i]; return sommedouble; int main(){ Tableau<int> t; t.ajouter(1); t.ajouter(2); t.ajouter(3); cout << fonction(t) << endl; cout << fonction(t) << endl; return 0; Que se passera-t-il? Indice : similaire à l opérateur =. Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 28 / 31

Code synthétisé par le compilateur pour le constructeur par copie template <class T> Tableau<T>::Tableau(const Tableau<T>& autre) : elements(autres.elements), capacite(autre.capacite), nbelements(autre.nbelements) { Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 29 / 31

Bon code pour le constructeur par copie template <class T> Tableau<T>::Tableau(const Tableau& autre) { capacite = autre.nbelements; // ou autre.capacite nbelements = autre.nbelements; elements = new T[capacite]; for(int i=0;i<nbelements;i++) elements[i] = autre.elements[i]; Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 30 / 31

Création d une classe générique Tableau<T> en C++ Lectures préalables : Sections 2 et 4 des notes de cours. Tâches : 1 Prendre connaissance des fichiers source dans lab3.zip. 2 Compléter la classe générique Tableau tel que présentée dans les notes de cours. 3 Tester avec test_tab.cpp. 4 Résoudre un problème simple (nuage de points) en appliquant un tableau. http://ericbeaudry.ca/inf3105/lab3/ Éric Beaudry (UQAM) INF3105 - Tableaux 2016A 31 / 31