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:
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.
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 :
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;
}
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()