Introduction au C++
Différences C/C++/Java, projet C++, syntaxe étendue, références, namespaces, premier programme orienté objet.
📄 Ressources du cours
🎥 Vidéos recommandées
-
🇫🇷
Vraiment bien comprendre la programmation objet en C++ (avec exemple) - Tuto débutant
Formation facile fr · 33:52 · 83k vues — Rejoignez cette chaîne pour bénéficier d'avantages exclusifs :https://www.youtube.com/channel/UCL37KTVyVCQnjQtNzbv_1EQ/joinDévelopper des jeux en C++ : https
-
🇫🇷
Classes, objets, attributs et méthodes en C++
MOOC EPFL Introduction à la programmation orientée objet (en C++) · 16:08 · 51k vues — Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
-
🇬🇧
C++ OOP - Introduction to classes and objects for beginners
CodeBeauty · 12:06 · 416k vues — Object-oriented programming is a programming paradigm that is based on the concept of objects from the real world, and it is used to represent those real wor...
1. Pourquoi C++ ?
- Très répandu — toujours dans le top 5 des langages industriels
- Rapide — compilé en code machine optimisé
- Portable — un même code source compile sur tous les OS
- Multi-paradigmes — procédural et orienté objet
Performance, contrôle bas niveau, immense écosystème de bibliothèques, expressivité (multi-paradigme).
Complexité importante, gestion mémoire manuelle (attention aux fuites), contrôle fin = plus de pièges.
C++ versus C
- C est un sous-ensemble de C++ — presque tout code C compile en C++
- C++ ajoute : programmation orientée objet, programmation générique (templates), type checking plus strict
C++ versus Java
| Aspect | C++ | Java |
|---|---|---|
| But | Efficacité d'exécution (performance) | Productivité du programmeur (portabilité) |
| Liberté | Faire confiance au programmeur | Imposer certaines contraintes |
| Paradigme | Procédural et orienté objet | Orienté objet |
| Mémoire | Manuelle (attention aux fuites !) | Garbage collection |
| Runtime | Code machine exécuté par l'OS · risques de buffer overflow, segfault | Byte code interprété par la JVM · exceptions |
| Performance | Compilation statique → code optimisé | Byte code, JIT (progrès) |
2. Outils & projet C++
Outils nécessaires
- Éditeur de texte — VSCode, Sublime, Vim…
- Compilateur —
g++,clang++,cl.exe(MSVC)… - Débogueur — gdb, lldb
- 3-en-1 = IDE (Environnement de Développement Intégré) — Code::Blocks, CLion, Visual Studio
Structure d'un projet C++
source.cpp ──→ [compile] ──→ object.o ──→ [link] ──→ executable
| Extension | Rôle |
|---|---|
.h / .hpp | Fichier de déclaration (header) — interface de la classe |
.cpp / .cc / .C | Fichier d'implémentation |
.o | Fichier objet (compilé, pas encore lié) |
.lib / .dll | Bibliothèque statique / dynamique |
Compilation avec g++
g++ -Wall -std=c++11 -c file.cpp # compile (warning all, C++11) -> file.o
g++ -o prog file1.o file2.o # link les objets -> executable
Un Makefile automatise ce processus pour les projets multi-fichiers.
Architecture d'un projet OO
L'en-tête .h sert d'interface : à la fois utilisée par les clients (user.cpp) et par l'implémentation (Vector.cpp).
3. Premier programme
#include <iostream> // bibliothèque d'entrées/sorties
using namespace std; // raccourci sur l'espace de noms std
int main()
{
cout << "Hello world!" << endl;
return 0;
}
#include <iostream>inclut la bibliothèque d'entrées/sortiesusing namespace std;évite de devoir préfixer chaque appel parstd::int main()est le point d'entrée du programme — comme en Ccout+ opérateur<<envoie sur la sortie standardendl= retour à la ligne
4. Spécificités C++ (hors objet)
Types
- Types C classiques :
int,char,float,double… - Booléen natif :
bool(avectrue/false) - Inférence de type :
auto—auto z = sqrt(y);infère le type - String : type natif via
#include <string>
Variables — convention de nommage
- Commencer par une minuscule
- Décomposer en plusieurs mots collés
- Chaque nouveau mot commence par une majuscule (sauf le premier)
- Exemple :
tauxOccupationSol
Initialisation
// Syntaxe historique (C)
int i = 7;
// Syntaxe avec parenthèses (préférée en C++)
int ageUser(18);
double pi(3.14159);
bool estMonAmi(true);
char lettre('a');
string nomUser("leVolontaire");
// Brace initialization (C++11) — plus stricte
double d2 {2.3}; // OK
int i {7.2}; // ERROR : narrowing interdit
int i = 7.2; // OK silencieusement (perte de précision)
Les
{ } empêchent toute conversion implicite avec perte (narrowing). Plus sûr que = ou ( ) qui acceptent silencieusement double → int.
Fonctions inline
inline int Max(int i, int j) {
if (i > j) return i;
else return j;
}
Le compilateur inline le code de la fonction à l'endroit de l'appel — pas d'overhead de l'appel. Réservé aux petites fonctions, pas de récursivité, pas de pointeur.
const et volatile
const
Rend impossible la modification de la variable. Évite les erreurs, aide aussi l'optimisation.
const int cst1 = 42;
const char* f(); // retourne const
void g(const int tab); // param const
void methodClass() const; // méthode const
volatile
Empêche les optimisations du compilateur sur cette variable — utile pour les variables modifiées hors du flot normal (interruption, hardware).
5. Références (&) et pointeurs
& dans le type pour déclarer une référence. La référence et la variable d'origine doivent être du même type.
int prixRevient(16); // déclaration d'une variable
int& prixAchat(prixRevient); // alias
prixAchat = 20; // modifie aussi prixRevient !
Pointeur vs Référence — choisir le plus sûr
Pointeur (héritage C) :
int i = 0;
int* pi = &i; // pointeur sur i
*pi = *pi + 1; // déréférencement
Référence (idiomatique C++) :
int i = 0;
int& ri = i; // alias
ri = ri + 1; // modifie i
Code plus lisible, pas de risque de pointeur nul ou pendant. Une référence ne peut pas changer de cible après initialisation — elle est moins flexible que le pointeur, mais aussi moins dangereuse.
Passage par référence
void test(int& i) {
i = 2; // modifie la variable d'origine
}
int x = 5;
test(x); // après cet appel : x == 2
Le passage par référence est plus efficace que par valeur (pas de copie) et permet à la fonction de modifier l'argument.
6. Namespaces
std::cout et monLib::cout peuvent coexister.
namespace first {
int x;
}
namespace second {
int x; // pas de collision : first::x ≠ second::x
}
int main() {
first::x = 1; // résolution explicite
using namespace first; // ouverture du namespace
x = 1; // désigne first::x
second::x = 2; // résolution explicite
}
7. Entrées / sorties standards
C++ redéfinit les I/O pour les simplifier. Tout est dans <iostream> et le namespace std.
| En C | En C++ | Rôle |
|---|---|---|
stdin | cin | Entrée standard |
stdout | cout | Sortie standard |
stderr | cerr | Sortie d'erreur |
printf | << (insertion) | Écriture |
scanf | >> (extraction) | Lecture |
#include <iostream>
using namespace std;
int main() {
int a;
cout << "saisir a ";
cin >> a;
cout << "le carré de " << a << " vaut " << a*a << endl;
}
8. Première classe — exemple Point
Une classe C++ se déclare typiquement dans un fichier d'en-tête .h et s'implémente dans un .cpp.
point.h — déclaration
#ifndef _POINT_HPP_
#define _POINT_HPP_
class Point {
private:
int x;
int y;
public:
void setX(int);
void setY(int);
int getX();
int getY();
};
#endif
point.cpp — implémentation
#include "point.h"
void Point::setX(int px) { x = px; }
void Point::setY(int py) { y = py; }
int Point::getX() { return x; }
int Point::getY() { return y; }
main.cpp — utilisation
#include <iostream>
#include "point.h"
using namespace std;
int main() {
Point p;
p.setX(3);
p.setY(4);
cout << "x = " << p.getX() << " y = " << p.getY();
return 0;
}
#ifndef / #define / #endif)
Évitent les inclusions multiples du même header dans une même unité de compilation (erreur de "redéfinition"). Indispensable.
Cette structure de base sera enrichie en SE2 avec les constructeurs et destructeurs.
★ Réviser le chapitre
Pour vérifier ta compréhension
Qu'est-ce qu'un objet en C++ ?
Un objet est une instance d'une classe. Il regroupe des attributs (données membres) et des méthodes (fonctions membres) qui agissent sur ces données.
Quelle est la différence entre public, private et protected ?
public : accessible partout. private : accessible uniquement à l'intérieur de la classe (par défaut). protected : accessible à l'intérieur de la classe et de ses classes dérivées.
À quoi sert le mot-clé this ?
this est un pointeur implicite vers l'objet courant. Il permet d'accéder aux membres d'un objet depuis l'intérieur d'une de ses méthodes. Utile pour distinguer un attribut d'un paramètre du même nom : this->x = x;
Quelle est la différence entre la déclaration et la définition d'une classe ?
La déclaration dans le .h (header) annonce l'existence de la classe et de ses membres. La définition des méthodes se fait dans le .cpp (implémentation), avec la syntaxe type Classe::methode(args) { … }. Cela permet de séparer interface et implémentation.
Pourquoi utilise-t-on des accesseurs (getters/setters) ?
Pour respecter l'encapsulation : les attributs restent private et seuls les accesseurs publics permettent d'y accéder. Cela permet de contrôler les modifications (validation), de modifier l'implémentation interne sans casser le code client, et de garantir des invariants.
🃏 Flashcards
#ifndef / #define / #endif ?int i {5} ?int i {7.2} est une erreur ; int i = 7.2 est silencieusement accepté.inline ?* et &. Préférer la référence.const sur une variable ?void f() const ?const à la fin de la signature.using namespace std; ?std dans le scope courant — on peut écrire cout au lieu de std::cout.cout << valeur;. Lire : cin >> variable;. Erreurs : cerr << …;. Tout est dans <iostream>.tauxOccupationSol.g++ -Wall -std=c++11 -c file.cpp ?file.cpp en file.o (objet, non lié) avec tous les warnings et la norme C++11.✎ Quiz éclair
cout et cin ?<iostream> fournit cin, cout, cerr — les flux d'entrée/sortie standards.{ } empêche le narrowing — int i {7.2} est une erreur. Les deux autres acceptent silencieusement.int a = 5; int& r = a; r = 10;, que vaut a ?r est un alias de a. Modifier r modifie a.inline ?const sur une méthode : int getX() const; ?.h et .cpp ?.h déclare l'interface (signatures, classes). Le .cpp implémente.Score : 0 / 7 ·