https://gist.github.com/krishnadey30/cb64bf875f29b5a6c91f79ea38a2ba4e

In C++, the concept of an "interface" is not explicitly defined as in some other languages (like Java or C#). However, you can achieve similar functionality using abstract classes and pure virtual functions. Here’s how it works:

Abstract Classes

An abstract class is a class that cannot be instantiated and is typically used to define an interface. You can create an abstract class by declaring at least one pure virtual function.

Pure Virtual Functions

A pure virtual function is declared by assigning 0 to the function declaration in the class. This signifies that the function must be implemented by any derived class.

#include <iostream>
#include <string>

// Define the interface using an abstract class
class IShape {
public:
    virtual double area() const = 0;        // Pure virtual function for area
    virtual double perimeter() const = 0;   // Pure virtual function for perimeter
    virtual ~IShape() {}  // Virtual destructor
};

// Implementing the interface in a derived class
class Rectangle : public IShape {
private:
    double width;
    double height;

public:
    Rectangle(double w, double h) : width(w), height(h) {}

    double area() const override {
        return width * height;
    }

    double perimeter() const override {
        return 2 * (width + height);
    }
};

// Another implementation of the interface
class Circle : public IShape {
private:
    double radius;

public:
    Circle(double r) : radius(r) {}

    double area() const override {
        return 3.14159 * radius * radius;  // Using Pi approximation
    }

    double perimeter() const override {
        return 2 * 3.14159 * radius;
    }
};

int main() {
    IShape* shape1 = new Rectangle(5.0, 3.0);
    IShape* shape2 = new Circle(2.0);

    std::cout << "Rectangle Area: " << shape1->area() << std::endl;
    std::cout << "Rectangle Perimeter: " << shape1->perimeter() << std::endl;

    std::cout << "Circle Area: " << shape2->area() << std::endl;
    std::cout << "Circle Perimeter: " << shape2->perimeter() << std::endl;

    // Clean up
    delete shape1;
    delete shape2;

    return 0;
}

a virtual function is a member function in a base class that you expect to override in derived classes. When you use a virtual function, C++ supports dynamic polymorphism, allowing you to call derived class methods through base class pointers or references.


#include <iostream>

// Base class
class Animal {
public:
    virtual void speak() const {  // Virtual function
        std::cout << "Animal speaks" << std::endl;
    }

    virtual ~Animal() { } // Virtual destructor
};

// Derived class
class Dog : public Animal {
public:
    void speak() const override {  // Override the base class function
        std::cout << "Woof!" << std::endl;
    }
};

// Another derived class
class Cat : public Animal {
public:
    void speak() const override {  // Override the base class function
        std::cout << "Meow!" << std::endl;
    }
};

int main() {
    Animal* animal1 = new Dog();  // Base class pointer to derived class object
    Animal* animal2 = new Cat();

    animal1->speak();  // Outputs: Woof!
    animal2->speak();  // Outputs: Meow!

    // Clean up
    delete animal1; 
    delete animal2;

    return 0;
}

Thread is lightweight object

example :

  1. browser has multiple tab that can be different thread.
  2. MS Word must be using multiple thread one for formatting the text another for processing the input(spell checker) other for auto saving

std::thread is the thread class that represents a single thread in C++. To start a thread we simply need to create a new thread object and pass the executing code to be called (i.e, a callable object) into the constructor of the object. Once the object is created a new thread is launched which will execute the code specified in callable.

this_thread::sleep_for : to make thread sleep

// Online C++ compiler to run C++ program online
#include <bits/stdc++.h>
using namespace std;
void findEven(int start, int end){
    int sum =0;
    for(int i=start;i<=end;i++){
        if(i%2==0)
            sum+=i;
    }
    **this_thread::sleep_for(**chrono::seconds(3)); // sleeping for 3 second 
    cout<<sum<<endl;
}
void findOdd(int start, int end){
    int sum =0;
    for(int i=start;i<=end;i++){
        if(i%2!=0)
            sum+=i;
    }
    cout<<sum;
}

int main() {
    // Write C++ code here
  
    thread t1(findEven, 1,10);
    thread t2(findOdd, 1,10);
    t1.join();
    if(t1.joinable())
	    t1.join()
    t2.join();
    return 0;
}

JOIN

To wait for a thread, use the std::thread::join() function. This function makes the current thread wait until the thread identified by *this has finished executing.

t1.join();: This line makes the main thread wait for t1 to finish executing. The join() function blocks the calling thread (main thread) until the thread t1 has completed its execution. If you don’t call join(), the main thread may finish and terminate the program before t1 has completed, which can lead to undefined behavior.

If needed we should check if thread is joinable or not by using joinable()