Cours C++ Complet 🚀

Les 16 chapitres essentiels pour apprendre le C++ — de la syntaxe de base au C++ moderne (C++20/23), avec exceptions, multithreading, fichiers, et 100+ exemples de code

16
Chapitres
100+
Exemples de code
C++20/23
Standard
A1→C2
Niveaux

CHAPITRE 01

Introduction et premier programme

🚀 Hello World

#include

int main()

// Avec using namespace (plus concis mais déconseillé dans les headers)
#include
using namespace std;

int main()

C++ vs C : C++ est un superset du C. Il ajoute la POO, les templates, la STL, les exceptions, les smart pointers, et bien plus. Tout code C valide est (presque) du C++ valide, mais le C++ moderne Ă©vite les patterns C (printf → cout, malloc → new/smart pointers).

⚙ Compiler et exĂ©cuter
# Compiler avec g++
g++ -std=c++20 -Wall -Wextra hello.cpp -o hello# Exécuter
./hello

# Avec clang++
clang++ -std=c++20 -Wall hello.cpp -o hello

# Avec CMake (projets multi-fichiers — standard en C++)
cmake -B build -DCMAKE_CXX_STANDARD=20
cmake –build build

đŸ—ïž C++ en rĂ©sumĂ©
CaractéristiqueC++
TypageStatique et fort
ParadigmeMulti-paradigme : POO + procédural + fonctionnel + générique
CompilationCompilé en code machine natif (trÚs rapide)
MémoireGestion manuelle (mais smart pointers en moderne)
UsageJeux (Unreal Engine), systÚmes, finance, embarqué, navigateurs (Chrome), IA/ML
ConventionPascalCase (classes), camelCase ou snake_case (variables/fonctions)
Standard actuelC++23 (2024), C++26 en cours de développement
🧠 Quiz
Quelle est la différence principale entre C et C++ ?
Le C++ ajoute la programmation orientée objet (classes, héritage, polymorphisme), les templates (generics), la STL (conteneurs/algorithmes), et la gestion mémoire automatique (smart pointers).

CHAPITRE 02

Variables et types de données

📩 Types fondamentaux
#include
#includeint main()

📝 std::string — mĂ©thodes essentielles

std::string s = « Hello World »;

s.length() // 11 (ou .size())
s.empty() // false
s.substr(0, 5) // « Hello »
s.find(« World ») // 6 (index, ou string::npos si pas trouvé)
s.replace(6, 5, « C++ ») // « Hello C++ »
s.append( » ! ») // « Hello C++ ! »
s[0] // 'H'
s.front() // 'H'
s.back() // '!'
s.starts_with(« He ») // true (C++20)
s.contains(« C++ ») // true (C++23)

// Comparaison avec == (pas besoin de strcmp !)
if (s == « Hello C++ ! »)

// Conversion
std::string n = std::to_string(42); // « 42 »
int val = std::stoi(« 42 »); // 42
double dval = std::stod(« 3.14 »); // 3.14

Toujours std::string en C++. Contrairement au C (char[]), std::string gÚre automatiquement la mémoire, supporte la concaténation avec +, la comparaison avec ==, et ne risque pas le buffer overflow.

🔄 RĂ©fĂ©rences
// Référence = alias pour une variable existante
int x = 10;
int& ref = x; // ref EST x (mĂȘme adresse mĂ©moire)
ref = 20; // x vaut maintenant 20// RĂ©fĂ©rence const — lecture seule
const int& cref = x;
cref = 30; // ❌ Erreur — const

// Différences pointeur vs référence :
// Pointeur : peut ĂȘtre NULL, peut changer de cible, syntaxe * et &
// Référence : JAMAIS null, liée à vie, syntaxe transparente

🧠 Quiz
Différence entre const et constexpr ?
const = non modifiable Ă  l'exĂ©cution (peut ĂȘtre initialisĂ© avec une valeur runtime). constexpr = calculĂ© Ă  la compilation (doit ĂȘtre une expression constante). constexpr est plus strict et plus optimisĂ©.

CHAPITRE 03

Opérateurs et flux I/O

đŸ–šïž EntrĂ©e / Sortie avec iostream
#include
#include
#include 

// C++20// Sortie — cout (chaünable avec <<)
std::cout << « Nom: «  << nom << « , Age: «  << age << « n »;

// std::format (C++20) — comme f-string Python
std::cout << std::format(« Nom: , Age: n », nom, age);
std::cout << std::format(« Pi = n », 3.14159); // Pi = 3.14

// std::print (C++23) — encore plus simple
std::print(« Nom: , Age: n », nom, age);

// EntrĂ©e — cin
int age;
std::cout << « Votre ùge : « ;
std::cin >> age;

// Lire une ligne entiĂšre (avec espaces)
std::string ligne;
std::getline(std::cin, ligne);

⚖ OpĂ©rateurs spĂ©cifiques C++

// Tous les opérateurs C + :

// Scope resolution (::)
std::cout // cout dans le namespace std
MyClass::method // méthode de MyClass

// new / delete (allocation dynamique C++)
int* p = new int(42);
delete p;

int* arr = new int[10];
delete[] arr; // ⚠ delete[] pour les tableaux

// Casts C++ (plus sûrs que le cast C)
static_cast<double>(7) / 2 // 3.5
dynamic_cast<Derived*>(basePtr) // Cast polymorphique (vérifié)

En C++ moderne, n'utilisez JAMAIS new/delete directement. Utilisez std::make_unique et std::make_shared (chapitre 11). Le new/delete nu est la source principale de memory leaks.

CHAPITRE 04

Structures conditionnelles

🔀 if, switch, if constexpr
// if / else — identique au C
if (age < 18) else // if avec initialisation (C++17)
if (auto it = map.find(key); it != map.end())

// switch — int, char, enum
switch (choix)

// if constexpr (C++17) — Ă©valuĂ© Ă  la compilation
template<typename T>
auto stringify(T value)

CHAPITRE 05

Boucles et tableaux

🔁 for, range-based for, while
// for classique
for (int i = 0; i < 5; i++) // Range-based for (C++11) — le plus utilisĂ©
std::vector<int> nums = ;
for (int n : nums)

// Par référence const (pas de copie, pas de modification)
for (const auto& n : nums)

// Par référence (pour modifier)
for (auto& n : nums)

📊 std::array et std::vector
#include
#include// std::array — taille fixe (remplacement du C array)
std::array<int, 5> arr = ;
arr.size() // 5
arr[0] // 10
arr.at(10) // ✅ Lùve une exception si hors limites

// std::vector — taille dynamique (LE plus utilisĂ©)
std::vector<int> vec = ;
vec.push_back(4); // Ajouter Ă  la fin
vec.pop_back(); // Retirer le dernier
vec.size() // 3
vec.empty() // false
vec.front() // 1
vec.back() // 3
vec.clear() // Vider
vec.erase(vec.begin()); // Supprimer le premier

RÚgle d'or : En C++ moderne, utilisez std::vector par défaut. N'utilisez les C arrays int arr[] que pour de l'embarqué ou du code trÚs contraint. std::array pour les tailles fixes connues à la compilation.

🧠 Quiz
Pourquoi utiliser const auto& dans un range-based for ?
const = on ne modifie pas l'élément. auto = le compilateur déduit le type. & = référence (évite de copier chaque élément). C'est le pattern par défaut pour la lecture.

CHAPITRE 06

Fonctions, enums et namespaces

⚡ Fonctions C++ : paramĂštres, surcharge, valeurs par dĂ©faut
// Passage par valeur (copie) — petits types
int square(int x) // Passage par const ref — gros objets (Ă©vite la copie)
void print(const std::string& s)

// Passage par rĂ©fĂ©rence — pour modifier
void increment(int& x)

// Valeurs par défaut
void greet(std::string name = « World »)

// Surcharge (overloading) — mĂȘme nom, types diffĂ©rents
int add(int a, int b)
double add(double a, double b)

// constexpr function — Ă©valuĂ©e Ă  la compilation
constexpr int factorial(int n)
constexpr int f5 = factorial(5); // 120, calculé à la compilation

RĂšgle des paramĂštres : petits types (int, double) → par valeur. Gros objets (string, vector, classes) → par const rĂ©fĂ©rence. Quand on veut modifier → par rĂ©fĂ©rence.

đŸ·ïž enum class (C++11) — type-safe
// ❌ Ancien enum C — polluent le scope
enum Color ;// ✅ enum class (C++11) — scoped, type-safe
enum class Color ;
enum class HttpStatus : int ;

Color c = Color::Red;
// int x = c; // ❌ Pas de conversion implicite — type-safe !

switch (c)

📩 Namespaces
namespace math
double a = math::area(5.0);// Nested namespaces (C++17)
namespace company::project::module { void init() }

Jamais using namespace std; dans un header (.h). Cela pollue l'espace de noms de tous les fichiers qui incluent le header. Dans un .cpp, c'est toléré mais déconseillé en production.

CHAPITRE 07

POO : Classes et objets

đŸ›ïž DĂ©finir une classe
class Person {
private:
std::string name_;
int age_;public:
// Constructeur
Person(std::string name, int age)
: name_{std::move(name)}, age_{age} // Liste d'initialisation

// Getters
const std::string& name() const { return name_; }
int age() const { return age_; }

// Setter
void set_age(int age) { age_ = age; }

// Méthode
std::string greet() const {
return « Bonjour, je suis «  + name_;
}

// Surcharge de l'opérateur <<
friend std::ostream& operator<<(std::ostream& os, const Person& p) {
os << p.name_ <<  » («  << p.age_ <<  » ans) »;
return os;
}
};

Person alice; // Uniform initialization
std::cout << alice << std::endl;

const aprĂšs une mĂ©thode signifie que la mĂ©thode ne modifie pas l'objet. Toutes les mĂ©thodes qui ne modifient pas l'Ă©tat doivent ĂȘtre const. C'est une convention fondamentale en C++.

⚡ struct vs class et Rule of Five
// struct = class avec public par défaut
struct Point ;// Rule of Five — si vous dĂ©finissez l'un, dĂ©finissez les 5 :
class Resource ;

// Rule of Zero (prĂ©fĂ©rĂ©) — si vous n'avez pas de ressource brute,
// ne définissez AUCUN des 5 et laissez le compilateur tout gérer

🧠 Quiz
Différence entre struct et class en C++ ?
Seule différence : struct = membres public par défaut. class = membres private par défaut. En pratique, struct est utilisé pour les données simples, class pour les objets avec logique.

CHAPITRE 08

Héritage, polymorphisme et templates

🔗 HĂ©ritage et virtual
class Animal {
protected:
std::string name_;
public:
Animal(std::string name) : name_{std::move(name)} // virtual = peut ĂȘtre surchargĂ©e (nĂ©cessaire pour le polymorphisme)
virtual std::string speak() const {
return name_ +  » fait du bruit »;
}

// Destructeur VIRTUEL — obligatoire si hĂ©ritage
virtual ~Animal() = default;
};

class Dog : public Animal {
public:
Dog(std::string name) : Animal{std::move(name)}

// override — vĂ©rifie Ă  la compilation que la mĂ©thode parent existe
std::string speak() const override {
return name_ +  » : Wouf ! »;
}
};

// Polymorphisme — fonctionne avec pointeurs/rĂ©fĂ©rences
std::unique_ptr<Animal> a = std::make_unique<Dog>(« Rex »);
std::cout << a->speak(); // « Rex : Wouf ! »

Destructeur virtuel OBLIGATOIRE sur toute classe de base. Sans lui, delete sur un pointeur de base ne détruira pas correctement l'objet dérivé (memory leak/undefined behavior).

⛔ final et pure virtual
// Classe abstraite — ne peut pas ĂȘtre instanciĂ©e
class Shape ;class Circle final : public Shape { // final = personne ne peut en hériter
double radius_;
public:
Circle(double r) : radius_{r}
double area() const override { return 3.14159 * radius_ * radius_; }
};

🔄 Function templates
// Template = code générique qui fonctionne avec tout type
template<typename T>
T max_val(T a, T b) max_val(3, 7); // T = int → retourne 7
max_val(3.14, 2.71); // T = double → retourne 3.14
max_valstring>(« a », « b »); // Explicit

// Concepts (C++20) — contraindre le type
template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

template<Numeric T>
T add(T a, T b)

add(3, 4); // ✅
add(« a », « b »); // ❌ string n'est pas Numeric

📩 Class templates
template<typename T>
class Stack ;Stack<int> intStack;
intStack.push(42);

Stackstring> strStack;
strStack.push(« hello »);

Concepts (C++20) remplacent SFINAE et les static_assert obscurs. Ils donnent des messages d'erreur clairs quand un type ne remplit pas le contrat. Similaire aux contraintes generics de TypeScript.

CHAPITRE 09

La STL : Conteneurs

📋 Les conteneurs principaux
ConteneurDescriptionAccĂšs
vectorTableau dynamique (le plus utilisé)O(1) par index
arrayTableau fixeO(1) par index
dequeFile à double extrémitéO(1) début/fin
listListe doublement chaßnéeO(n) accÚs, O(1) insertion
setÉlĂ©ments uniques, triĂ©sO(log n)
unordered_setÉlĂ©ments uniques, hashO(1) moyen
mapClé/valeur, triées par cléO(log n)
unordered_mapClé/valeur, hashO(1) moyen
stackLIFOO(1) top
queueFIFOO(1) front/back
🔧 map et unordered_map

#include

std::unordered_mapstring, int> ages = {
,
{« Bob », 30},
};

// AccĂšs
ages[« Alice »] // 25 (⚠ crĂ©e une entrĂ©e si clĂ© absente)
ages.at(« Alice ») // 25 (lance exception si clé absente)
ages.count(« Eve ») // 0 (n'existe pas)
ages.contains(« Bob ») // true (C++20)

// Itérer
for (const auto& [nom, age] : ages)

// Insérer / supprimer
ages.insert();
ages.erase(« Bob »);

🧠 Quiz
Quand utiliser map vs unordered_map ?
unordered_map = O(1) moyen, plus rapide pour la plupart des cas. map = O(log n) mais éléments triés par clé. Utilisez map uniquement si l'ordre des clés importe.

CHAPITRE 10

La STL : Algorithmes et lambdas

⚡ Expressions lambda (C++11)
// Lambda = fonction anonyme inline
// [capture](params) -> retour auto add = [](int a, int b) ;
add(3, 4); // 7

// Captures
int x = 10;
auto f1 = [x]() ; // Copie de x
auto f2 = [&x]() ; // Référence vers x
auto f3 = [=]() ; // Copie de tout
auto f4 = [&]() ; // Référence à tout

// Generic lambda (C++14)
auto print = [](const auto& val) ;

🔧 Algorithmes STL
#include
#include
#include // C++20std::vector<int> v = ;

// Trier
std::sort(v.begin(), v.end()); //
std::sort(v.begin(), v.end(), std::greater<>()); // Décroissant

// Chercher
auto it = std::find(v.begin(), v.end(), 8);
bool found = std::binary_search(v.begin(), v.end(), 5); // O(log n)

// Transformer
std::vector<int> doubled;
std::transform(v.begin(), v.end(), std::back_inserter(doubled),[](int n) );

// Filtrer (C++20 Ranges)
auto evens = v | std::views::filter([](int n) );

// ChaĂźnage Ranges (C++20)
auto result = v
| std::views::filter([](int n) )
| std::views::transform([](int n) );

// Autres
std::count_if(v.begin(), v.end(), [](int n) );
std::accumulate(v.begin(), v.end(), 0); // Somme
std::min_element(v.begin(), v.end());
std::max_element(v.begin(), v.end());
std::any_of(v.begin(), v.end(), [](int n) );
std::all_of(v.begin(), v.end(), [](int n) );

C++20 Ranges = la révolution. Chaßnez les opérations avec le pipe |, comme les Streams Java ou LINQ C#. Plus besoin de begin()/end() partout.

CHAPITRE 11

Gestion mémoire moderne

đŸ›Ąïž Smart Pointers (C++11)

#include

// unique_ptr — propriĂ©taire UNIQUE (pas de copie, move uniquement)
auto ptr = std::make_unique<Person>(« Alice », 25);
ptr->greet(); // Utilisation identique Ă  un pointeur brut
// DĂ©truit automatiquement quand ptr sort du scope ✅

// Transférer la propriété
auto ptr2 = std::move(ptr); // ptr est maintenant nullptr

// shared_ptr — propriĂ©tĂ© partagĂ©e (compteur de rĂ©fĂ©rences)
auto sp1 = std::make_shared<Person>(« Bob », 30);
auto sp2 = sp1; // 2 shared_ptr pointent vers le mĂȘme objet
sp1.use_count() // 2
// Détruit quand le dernier shared_ptr est détruit

// weak_ptr — observe sans possĂ©der (Ă©vite les cycles)
std::weak_ptr<Person> wp = sp1;
if (auto locked = wp.lock())

RÚgle : jamais de new/delete nu. Utilisez make_unique (99% des cas) ou make_shared (propriété partagée). Les smart pointers garantissent la libération automatique et éliminent les memory leaks.

🔄 Move semantics et RAII
// RAII = Resource Acquisition Is Initialization
// = les ressources sont liées à la durée de vie d'un objet// Le destructeur nettoie automatiquement
{
std::vector<int> v = ; // Allocation
// 
 utilisation de v 

} // v dĂ©truit automatiquement, mĂ©moire libĂ©rĂ©e ✅

// Move semantics — transfĂ©rer au lieu de copier
std::vector<int> createBigVector()

std::vector<int> data = createBigVector(); // Move, O(1)

🧠 Quiz
Quand utiliser unique_ptr vs shared_ptr ?
unique_ptr = quand un seul propriĂ©taire (99% des cas, zĂ©ro overhead). shared_ptr = quand plusieurs objets doivent partager la mĂȘme ressource (compteur de rĂ©fĂ©rences, petit overhead).

CHAPITRE 12

Exceptions et gestion d'erreurs

🚹 try / catch / throw

#include

double divide(double a, double b)

try catch (const std::invalid_argument& e) catch (const std::exception& e) catch (
)

📋 Exceptions standard et bonnes pratiques
ExceptionUsage
std::runtime_errorErreur à l'exécution (fichier introuvable, réseau
)
std::invalid_argumentArgument invalide passé à une fonction
std::out_of_rangeIndex hors limites (vector::at())
std::bad_allocAllocation mémoire échouée

noexcept : marquez les fonctions qui ne lancent jamais d'exception avec noexcept. Le compilateur optimise mieux, et les conteneurs STL en profitent (move constructors noexcept utilisés par vector lors du redimensionnement).

Exceptions vs optional : pour les erreurs « attendues » (fichier absent, entrée invalide), std::optional ou std::expected (C++23) sont souvent préférés car ils n'ont pas le coût du déroulement de pile.

CHAPITRE 13

Fichiers et flux (fstream)

📄 Lire et Ă©crire des fichiers
#include
#include// Écrire dans un fichier
std::ofstream out(« data.txt »);
if (out.is_open()) // Fichier fermĂ© automatiquement (RAII) ✅

// Lire ligne par ligne
std::ifstream in(« data.txt »);
std::string line;
while (std::getline(in, line))

// Lire tout le fichier d'un coup
std::ifstream file(« data.txt »);
std::string content(
(std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>()
);

// std::filesystem (C++17) — manipuler chemins et fichiers
#include
namespace fs = std::filesystem;

fs::exists(« data.txt »); // true
fs::file_size(« data.txt »); // taille en octets
fs::remove(« old.txt »); // supprimer
for (auto& entry : fs::directory_iterator(« . »))

RAII pour les fichiers : pas besoin de .close() explicite. Le destructeur de fstream ferme automatiquement le fichier quand l'objet sort du scope. C'est la force du C++ moderne.

CHAPITRE 14

Multithreading (std::thread)

đŸ§” Threads et synchronisation
#include
#include
#include// Créer un thread
void work(int id)

std::thread t1(work, 1);
std::thread t2(work, 2);
t1.join(); // Attendre la fin
t2.join();

// Mutex — protĂ©ger une ressource partagĂ©e
std::mutex mtx;
int counter = 0;

void safe_increment() // lock libéré automatiquement

// async — lancer une tĂąche et rĂ©cupĂ©rer le rĂ©sultat
auto future = std::async(std::launch::async, []() );
int result = future.get(); // Bloque jusqu'au résultat

Toujours utiliser std::lock_guard ou std::scoped_lock (C++17) pour les mutex. Ne jamais faire mtx.lock() / mtx.unlock() manuellement — risque de deadlock si une exception est lancĂ©e entre les deux.

std::jthread (C++20) est une version améliorée de thread qui appelle .join() automatiquement dans son destructeur (RAII). Préférez jthread quand votre compilateur le supporte.

CHAPITRE 15

C++ moderne (17/20/23)

⚡ C++17 Features
// Structured bindings
auto [nom, age] = std::make_pair(« Alice », 25);
for (const auto& [key, val] : myMap) // std::optional — valeur qui peut ĂȘtre absente
std::optional<int> findAge(const std::string& name)
auto age = findAge(« Alice »);
if (age.has_value()) std::cout << *age;
int val = age.value_or(0);

// std::variant — union type-safe
std::variant<int, std::string> v = 42;
v = « hello »;
if (std::holds_alternativestring>(v))

// if constexpr — branches Ă©valuĂ©es Ă  la compilation
// std::filesystem — manipuler fichiers/dossiers
// std::string_view — rĂ©fĂ©rence non-possĂ©dante vers une string

🚀 C++20 Features
// Ranges — chaünage fonctionnel
auto result = nums
| std::views::filter([](int n) )
| std::views::transform([](int n) )
| std::views::take(5);// Concepts — contraintes lisibles
templateT>
T gcd(T a, T b)

// Three-way comparison (spaceship operator)
auto r = 5 <=> 3; // std::strong_ordering::greater

// std::format — formatage type-safe
std::cout << std::format(« Pi =  », 3.14159);

// Coroutines (co_await, co_yield, co_return)
// Modules (import std; — remplace #include)
// Designated initializers
Point p = ;
// std::jthread — thread avec RAII (auto-join)

🆕 C++23 Features
// std::print — remplacement de cout (enfin !)
std::print(« Nom: , Age: n », « Alice », 25);
std::println(« Avec saut de ligne automatique »);// std::expected — gestion d'erreur sans exception
std::expected<int, std::string> parse_int(const std::string& s)
auto r = parse_int(« 42 »);
if (r.has_value()) std::cout << *r;

// string::contains (enfin !)
std::string s = « Hello C++23 »;
s.contains(« C++ »); // true

// std::flat_map — map basĂ©e sur des vecteurs triĂ©s (plus rapide)
// Deducing this — simplifie les patterns CRTP
// std::generator — gĂ©nĂ©rateur coroutine simple
// Multidimensional subscript operator: matrix[x, y]
// if consteval — tester si on est Ă©valuĂ© Ă  la compilation

std::expected (C++23) est l'alternative moderne aux exceptions pour les erreurs « attendues ». Comme Result en Rust. Pas de coût de déroulement de pile, et le type d'erreur est explicite dans la signature.

🧠 Quiz
Que remplace std::optional ?
Il remplace le pattern « retourner -1 ou nullptr pour dire absent ». optional exprime explicitement qu'une valeur peut ĂȘtre prĂ©sente ou absente, de façon type-safe.
Qu'est-ce que RAII ?
Resource Acquisition Is Initialization. Les ressources (mémoire, fichiers, connexions) sont liées à la durée de vie d'un objet. Le destructeur libÚre automatiquement quand l'objet sort du scope. C'est LE principe fondamental du C++ moderne.

CHAPITRE 16

Bonnes pratiques et outils C++

✅ Bonnes pratiques C++ moderne

✅ À FAIRE
‱ -std=c++20 -Wall -Wextra
‱ auto quand le type est Ă©vident
‱ const et constexpr partout
‱ make_unique / make_shared
‱ vector par dĂ©faut
‱ string_view pour les paramùtres
‱ Ranges pour les algorithmes
‱ override / final explicit
‱ RAII (pas de resource leak)
‱ enum class au lieu de enum
‱ noexcept sur les move constructors

❌ À ÉVITER
‱ new / delete nus
‱ C arrays int arr[]
‱ using namespace std dans les headers
‱ printf / scanf (utiliser cout / format)
‱ C-style casts (int)x
‱ malloc / free (c'est du C)
‱ Macros pour les constantes (#define)
‱ Retourner des raw pointers
‱ Variables non initialisĂ©es
‱ mtx.lock() sans lock_guard

🔧 Outils essentiels pour le C++
OutilUsage
CMakeSystùme de build standard — CMakeLists.txt
clang-tidyLinter — dĂ©tecte les mauvaises pratiques
AddressSanitizer-fsanitize=address — dĂ©tecte les accĂšs mĂ©moire invalides
ValgrindDétecte les memory leaks à l'exécution
clang-formatFormatage automatique du code
Conan / vcpkgGestionnaires de paquets C++
Compiler Explorergodbolt.org — voir l'assembleur gĂ©nĂ©rĂ© en ligne
🧠 Quiz
Que remplace std::optional ?
Il remplace le pattern « retourner -1 ou nullptr pour dire absent ». optional exprime explicitement qu'une valeur peut ĂȘtre prĂ©sente ou absente, de façon type-safe.
Qu'est-ce que RAII ?
Resource Acquisition Is Initialization. Les ressources (mémoire, fichiers, connexions) sont liées à la durée de vie d'un objet. Le destructeur libÚre automatiquement quand l'objet sort du scope. C'est LE principe fondamental du C++ moderne.

Cours C++ Complet — Des bases au C++ moderne (C++20/23)

Référence : cppreference.com | isocpp.org