← Back to My Courses 2023-2024

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:

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:


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

Héritage et polymorphisme C++

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:

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:

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

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:

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.


📚 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.

📥 Télécharger

📖 Partie 2 - Classes

Classes en C++ : constructeurs, destructeurs, encapsulation, membres privés/publics et méthodes.

📥 Télécharger

📖 Partie 3 - Héritage

Héritage en C++ : classes dérivées, constructeurs/destructeurs en cascade, accès protected.

📥 Télécharger

📖 Partie 4 - Polymorphisme

Polymorphisme en C++ : fonctions virtuelles, classes abstraites, liaison dynamique et virtual.

📥 Télécharger