Programmation Orientée Objets C++
PART A: GENERALITIES
Presentation
The “Programmation Orientée Objets C++” course provided a comprehensive introduction to object-oriented programming using C++. This course was essential for developing modern software applications with emphasis on code reusability, maintainability, and efficient memory management. C++ combines the power of low-level programming with high-level object-oriented features.
Academic Year: 2023-2024
Semester: 7
Category: Programming
PART B: DESCRIPTIVE PART
Supports de cours:
| Partie 1 (PDF) | Partie 2 (PDF) | Partie 3 (PDF) | Partie 4 (PDF) | Partie 5 (PDF) | Partie 6 (PDF) | Partie 7 (PDF) |
Experience Details
Environment and Context
The course covered both theoretical concepts and practical implementation of object-oriented programming in C++. We used modern C++ development environments and worked on progressively complex projects that demonstrated the power and flexibility of OOP principles in C++.
My Function
In this course, I was responsible for:
- Understanding core OOP concepts (encapsulation, inheritance, polymorphism)
- Implementing classes and objects in C++
- Managing memory allocation and deallocation
- Using templates and the Standard Template Library (STL)
- Applying design patterns in C++ applications
- Debugging and optimizing C++ code
PART C: TECHNICAL PART
This section explores the technical aspects of object-oriented programming in C++.
Technical Concepts Learned
1. Classes and Objects
The foundation of OOP in C++:
Class Definition:
class Rectangle {
private:
double width;
double height;
public:
// Constructor
Rectangle(double w, double h) : width(w), height(h) {}
// Member functions
double area() const {
return width * height;
}
double perimeter() const {
return 2 * (width + height);
}
// Getters and setters
void setWidth(double w) { width = w; }
double getWidth() const { return width; }
};
Key Concepts:
- Encapsulation: Data hiding using private/protected/public access specifiers
- Constructor/Destructor: Object initialization and cleanup
- Member Functions: Methods that operate on object data
- Const Correctness: Using const for read-only operations
2. Constructors and Destructors
Special member functions for object lifecycle management:
class DynamicArray {
private:
int* data;
size_t size;
public:
// Default constructor
DynamicArray() : data(nullptr), size(0) {}
// Parameterized constructor
DynamicArray(size_t n) : size(n) {
data = new int[size];
}
// Copy constructor
DynamicArray(const DynamicArray& other) : size(other.size) {
data = new int[size];
std::copy(other.data, other.data + size, data);
}
// Move constructor (C++11)
DynamicArray(DynamicArray&& other) noexcept
: data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
}
// Destructor
~DynamicArray() {
delete[] data;
}
// Copy assignment operator
DynamicArray& operator=(const DynamicArray& other) {
if (this != &other) {
delete[] data;
size = other.size;
data = new int[size];
std::copy(other.data, other.data + size, data);
}
return *this;
}
};
Rule of Three/Five: If you need to define a custom destructor, copy constructor, or copy assignment operator, you likely need all three (or five with move semantics).
3. Inheritance
Figure : Héritage et polymorphisme en C++ - Classe de base Animal et classes dérivées
Code reuse through class hierarchies:
class Shape {
protected:
std::string color;
public:
Shape(const std::string& c) : color(c) {}
virtual ~Shape() {} // Virtual destructor
virtual double area() const = 0; // Pure virtual function
virtual void draw() const {
std::cout << "Drawing a " << color << " shape\n";
}
};
class Circle : public Shape {
private:
double radius;
public:
Circle(const std::string& c, double r)
: Shape(c), radius(r) {}
double area() const override {
return M_PI * radius * radius;
}
void draw() const override {
std::cout << "Drawing a " << color << " circle\n";
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(const std::string& c, double w, double h)
: Shape(c), width(w), height(h) {}
double area() const override {
return width * height;
}
};
Inheritance Types:
- Public Inheritance: Is-a relationship
- Protected Inheritance: Implementation inheritance
- Private Inheritance: Not commonly used
4. Polymorphism
Dynamic dispatch through virtual functions:
void printArea(const Shape& shape) {
std::cout << "Area: " << shape.area() << std::endl;
shape.draw();
}
int main() {
Circle circle("red", 5.0);
Rectangle rect("blue", 4.0, 6.0);
printArea(circle); // Calls Circle::area()
printArea(rect); // Calls Rectangle::area()
// Polymorphic container
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>("green", 3.0));
shapes.push_back(std::make_unique<Rectangle>("yellow", 2.0, 5.0));
for (const auto& shape : shapes) {
shape->draw();
}
}
Key Concepts:
- Virtual Functions: Enable runtime polymorphism
- Virtual Destructor: Essential for base classes
- Pure Virtual Functions: Define abstract interfaces
- Override Keyword: Explicit override declaration (C++11)
5. Operator Overloading
Defining custom behavior for operators:
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// Arithmetic operators
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
Complex operator*(const Complex& other) const {
return Complex(
real * other.real - imag * other.imag,
real * other.imag + imag * other.real
);
}
// Comparison operator
bool operator==(const Complex& other) const {
return real == other.real && imag == other.imag;
}
// Stream operators (as friend functions)
friend std::ostream& operator<<(std::ostream& os, const Complex& c) {
os << c.real << " + " << c.imag << "i";
return os;
}
friend std::istream& operator>>(std::istream& is, Complex& c) {
is >> c.real >> c.imag;
return is;
}
};
6. Templates
Generic programming for code reusability:
// Function template
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// Class template
template<typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
T pop() {
if (elements.empty()) {
throw std::runtime_error("Stack is empty");
}
T value = elements.back();
elements.pop_back();
return value;
}
bool empty() const {
return elements.empty();
}
size_t size() const {
return elements.size();
}
};
// Template specialization
template<>
class Stack<bool> {
// Specialized implementation for bool
};
7. Standard Template Library (STL)
Powerful collection of generic containers and algorithms:
Containers:
// Sequential containers
std::vector<int> vec = {1, 2, 3, 4, 5};
std::list<std::string> lst;
std::deque<double> deq;
// Associative containers
std::map<std::string, int> ages;
ages["Alice"] = 25;
ages["Bob"] = 30;
std::set<int> unique_numbers = {1, 2, 3, 3, 4}; // {1, 2, 3, 4}
// Container adapters
std::stack<int> stack;
std::queue<int> queue;
std::priority_queue<int> pq;
Algorithms:
#include <algorithm>
std::vector<int> numbers = {5, 2, 8, 1, 9};
// Sorting
std::sort(numbers.begin(), numbers.end());
// Finding
auto it = std::find(numbers.begin(), numbers.end(), 8);
// Transforming
std::transform(numbers.begin(), numbers.end(), numbers.begin(),
[](int n) { return n * 2; });
// Accumulating
int sum = std::accumulate(numbers.begin(), numbers.end(), 0);
8. Smart Pointers (C++11)
Automatic memory management:
#include <memory>
// Unique pointer (exclusive ownership)
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
// Shared pointer (shared ownership)
std::shared_ptr<int> ptr2 = std::make_shared<int>(100);
std::shared_ptr<int> ptr3 = ptr2; // Reference count = 2
// Weak pointer (non-owning reference)
std::weak_ptr<int> weak = ptr2;
// Example with classes
class MyClass {
public:
MyClass() { std::cout << "Constructor\n"; }
~MyClass() { std::cout << "Destructor\n"; }
void doSomething() { std::cout << "Doing something\n"; }
};
std::unique_ptr<MyClass> obj = std::make_unique<MyClass>();
obj->doSomething();
// Destructor called automatically when obj goes out of scope
9. Exception Handling
Robust error management:
class FileNotFoundException : public std::exception {
private:
std::string message;
public:
FileNotFoundException(const std::string& filename)
: message("File not found: " + filename) {}
const char* what() const noexcept override {
return message.c_str();
}
};
void readFile(const std::string& filename) {
try {
std::ifstream file(filename);
if (!file.is_open()) {
throw FileNotFoundException(filename);
}
// Read file...
} catch (const FileNotFoundException& e) {
std::cerr << "Error: " << e.what() << std::endl;
throw; // Re-throw
} catch (const std::exception& e) {
std::cerr << "Unexpected error: " << e.what() << std::endl;
}
}
10. Design Patterns
Common software design solutions:
Singleton Pattern:
class Database {
private:
static Database* instance;
Database() {} // Private constructor
public:
static Database* getInstance() {
if (instance == nullptr) {
instance = new Database();
}
return instance;
}
void connect() {
std::cout << "Connecting to database...\n";
}
};
Factory Pattern:
class ShapeFactory {
public:
static std::unique_ptr<Shape> createShape(const std::string& type) {
if (type == "circle") {
return std::make_unique<Circle>("red", 5.0);
} else if (type == "rectangle") {
return std::make_unique<Rectangle>("blue", 4.0, 6.0);
}
return nullptr;
}
};
PART D: ANALYTICAL PART
Knowledge and Skills Mobilized
- Understanding object-oriented programming principles
- Implementing classes with proper encapsulation
- Using inheritance and polymorphism effectively
- Managing memory with RAII and smart pointers
- Applying templates for generic programming
- Utilizing STL containers and algorithms
- Handling exceptions properly
- Implementing design patterns
- Debugging complex C++ programs
Self Evaluation
This course was challenging but rewarding. Coming from C programming, the shift to object-oriented thinking required significant mental adjustment. The concept of classes and objects was initially abstract, but through practical projects, I gained solid understanding.
Memory management in C++ (especially with pointers and dynamic allocation) was tricky. However, learning about RAII and smart pointers made memory management much more manageable and safer. The introduction of C++11 features like move semantics and lambda functions was particularly interesting.
Templates and the STL initially seemed overwhelming due to their complexity, but I came to appreciate their power for writing generic, reusable code. The error messages from template compilation errors were often cryptic and difficult to debug.
I found polymorphism and virtual functions fascinating, especially how they enable flexible and extensible software design. Implementing design patterns helped me understand professional software architecture.
My Opinion
C++ is a powerful but complex language. This course provided a solid foundation in OOP with C++, though mastering the language requires continuous practice. The course balanced theory with practical implementation well.
I particularly appreciated learning about modern C++ features (C++11/14/17). These features make C++ more user-friendly while maintaining its performance advantages. Understanding the relationship between C and C++ helped me appreciate when to use C++’s features versus C-style programming.
Areas I would have liked to explore more:
- Multithreading and concurrency in C++
- Template metaprogramming
- More complex design patterns
- Performance optimization techniques
- Build systems and project organization
The projects helped solidify concepts, though more real-world applications (like embedded systems programming or game development) would have been valuable. Overall, this course equipped me with essential skills for modern software development.
Illustrations du Projet Gamelle Connectee
Figure : Diagramme de classes UML du projet Gamelle Connectee
Figure : Application Gamelle Connectee - interface client
Figure : Architecture serveur du projet Gamelle Connectee
Rapports et Projets
Rapport Gamelle Connectee
Rapport du projet de programmation orientee objets C++ : conception et implementation d'une gamelle connectee avec architecture client-serveur.
📚 Documents de Cours
📖 Partie 1 - Bases C++
Introduction au C++ : différences avec C, compilation, entrées/sorties, références et gestion mémoire.
📖 Partie 2 - Classes
Classes en C++ : constructeurs, destructeurs, encapsulation, membres privés/publics et méthodes.
📖 Partie 3 - Héritage
Héritage en C++ : classes dérivées, constructeurs/destructeurs en cascade, accès protected.
📖 Partie 4 - Polymorphisme
Polymorphisme en C++ : fonctions virtuelles, classes abstraites, liaison dynamique et virtual.