Les templates permettent d'écrire du code générique qui fonctionne avec différents types.
#include <iostream>
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
int main() {
std::cout << maximum(10, 20) << std::endl; // int
std::cout << maximum(3.14, 2.71) << std::endl; // double
std::cout << maximum('a', 'z') << std::endl; // char
return 0;
}#include <iostream>
template <typename T>
class Boite {
private:
T contenu;
public:
Boite(T val) : contenu(val) {}
T getContenu() { return contenu; }
void setContenu(T val) { contenu = val; }
};
int main() {
Boite<int> boiteInt(42);
Boite<std::string> boiteStr("Hello");
std::cout << boiteInt.getContenu() << std::endl;
std::cout << boiteStr.getContenu() << std::endl;
return 0;
}#include <iostream>
#include <string>
class Animal {
protected:
std::string nom;
int age;
public:
Animal(std::string n, int a) : nom(n), age(a) {}
virtual void faireDuBruit() {
std::cout << "L'animal fait du bruit" << std::endl;
}
void afficher() {
std::cout << nom << ", " << age << " ans" << std::endl;
}
};
class Chien : public Animal {
public:
Chien(std::string n, int a) : Animal(n, a) {}
void faireDuBruit() override {
std::cout << "Woof! Woof!" << std::endl;
}
};
class Chat : public Animal {
public:
Chat(std::string n, int a) : Animal(n, a) {}
void faireDuBruit() override {
std::cout << "Miaou!" << std::endl;
}
};
int main() {
Chien rex("Rex", 3);
Chat felix("Felix", 2);
rex.afficher();
rex.faireDuBruit();
felix.afficher();
felix.faireDuBruit();
// Polymorphisme
Animal* animal = &rex;
animal->faireDuBruit(); // Woof! Woof!
return 0;
}virtual permet le polymorphisme. Utilisez override pour indiquer qu'une méthode redéfinit une méthode virtuelle.
Les smart pointers gÚrent automatiquement la mémoire et évitent les fuites mémoire.
#include <iostream>
#include <memory>
class Personne {
public:
std::string nom;
Personne(std::string n) : nom(n) {
std::cout << "Création de " << nom << std::endl;
}
~Personne() {
std::cout << "Destruction de " << nom << std::endl;
}
};
int main() {
std::unique_ptr<Personne> p1 = std::make_unique<Personne>("Alice");
std::cout << p1->nom << std::endl;
// p1 sera automatiquement libéré à la fin du scope
return 0;
}#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> p1 = std::make_shared<int>(42);
std::cout << "Compteur: " << p1.use_count() << std::endl; // 1
{
std::shared_ptr<int> p2 = p1;
std::cout << "Compteur: " << p1.use_count() << std::endl; // 2
} // p2 détruit ici
std::cout << "Compteur: " << p1.use_count() << std::endl; // 1
return 0;
}#include <iostream>
#include <stdexcept>
double diviser(double a, double b) {
if (b == 0) {
throw std::runtime_error("Division par zéro!");
}
return a / b;
}
int main() {
try {
double resultat = diviser(10, 2);
std::cout << "Résultat: " << resultat << std::endl;
resultat = diviser(10, 0); // Lance une exception
std::cout << "Ceci ne s'affichera pas" << std::endl;
}
catch (const std::runtime_error& e) {
std::cout << "Erreur: " << e.what() << std::endl;
}
catch (...) {
std::cout << "Erreur inconnue" << std::endl;
}
std::cout << "Programme continue..." << std::endl;
return 0;
}#include <iostream>
#include <exception>
class MonException : public std::exception {
private:
std::string message;
public:
MonException(const std::string& msg) : message(msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
void verifierAge(int age) {
if (age < 18) {
throw MonException("Vous devez ĂȘtre majeur!");
}
}
int main() {
try {
verifierAge(15);
}
catch (const MonException& e) {
std::cout << e.what() << std::endl;
}
return 0;
}#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Lambda simple
auto saluer = []() {
std::cout << "Bonjour!" << std::endl;
};
saluer();
// Lambda avec paramĂštres
auto additionner = [](int a, int b) {
return a + b;
};
std::cout << additionner(5, 3) << std::endl;
// Capture de variables
int multiplicateur = 10;
auto multiplier = [multiplicateur](int x) {
return x * multiplicateur;
};
std::cout << multiplier(5) << std::endl;
// Utilisation avec STL
std::vector<int> nombres = {1, 2, 3, 4, 5};
std::for_each(nombres.begin(), nombres.end(), [](int n) {
std::cout << n * 2 << " ";
});
return 0;
}#include <iostream>
#include <vector>
#include <string>
class Donnees {
private:
std::vector<int> data;
public:
// Constructeur
Donnees(size_t taille) : data(taille) {
std::cout << "Constructeur" << std::endl;
}
// Copy constructor
Donnees(const Donnees& autre) : data(autre.data) {
std::cout << "Copy constructor" << std::endl;
}
// Move constructor
Donnees(Donnees&& autre) noexcept : data(std::move(autre.data)) {
std::cout << "Move constructor" << std::endl;
}
// Copy assignment
Donnees& operator=(const Donnees& autre) {
std::cout << "Copy assignment" << std::endl;
data = autre.data;
return *this;
}
// Move assignment
Donnees& operator=(Donnees&& autre) noexcept {
std::cout << "Move assignment" << std::endl;
data = std::move(autre.data);
return *this;
}
};
int main() {
Donnees d1(1000);
Donnees d2 = std::move(d1); // Move constructor
return 0;
}#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx;
int compteur = 0;
void incrementer(int n) {
for (int i = 0; i < n; i++) {
std::lock_guard<std::mutex> lock(mtx);
compteur++;
}
}
int main() {
std::vector<std::thread> threads;
// Créer 5 threads
for (int i = 0; i < 5; i++) {
threads.push_back(std::thread(incrementer, 1000));
}
// Attendre tous les threads
for (auto& t : threads) {
t.join();
}
std::cout << "Compteur final: " << compteur << std::endl;
return 0;
}-pthread