#include<bits/stdc++.h>
#define IOF ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
#define ll long long
#define pb public:
#define pr private:
using namespace std;
class Complex{
float real , imag;
public:
Complex(){
real = imag = 0;
cout << "This is the default constructor\n";
}
Complex(float f){
real = imag = f;
cout << "This is the overloaded constructor , with 1 parameter\n";
}
Complex(float f1 , float f2){
real = f1;
imag = f2;
cout << "This is the overloaded constructor , with 2 parameters\n";
}
void setReal(float r){
real = r;
}
void setImag(float i){
imag = i;
}
float getReal(){
return real;
}
float getImag(){
return imag;
}
void print(){
cout << real << (imag < 0 ? " - " : " + ") << abs(imag) << 'i' << '\n';
}
Complex add(Complex c){
Complex tmp;
tmp.real = real + c.getReal();
tmp.imag = imag + c.getImag();
return tmp;
}
Complex sub(Complex c){
Complex tmp;
tmp.real = real - c.getReal();
tmp.imag = imag - c.getImag();
return tmp;
}
friend Complex addTo(float v , Complex c);
~Complex(){
cout << "the object is destroyed\n";
}
Complex operator +(Complex & c){
Complex tmp;
tmp.real = real + c.real;
tmp.imag = imag + c.imag;
return tmp;
}
Complex operator +(float f){
Complex tmp;
tmp.real = real + f;
tmp.imag = imag;
return tmp;
}
Complex operator -(float f){
Complex tmp;
tmp.real = real - f;
tmp.imag = imag;
return tmp;
}
Complex operator -(Complex & c){
Complex tmp;
tmp.real = real - c.real;
tmp.imag = imag - c.imag;
return tmp;
}
friend Complex operator +(float f , Complex & c);
friend Complex operator -(float f , Complex & c);
bool operator == (Complex & c){
return (real == c.real && imag == c.imag);
}
void operator +=(Complex & c){
real += c.real;
imag += c.imag;
}
Complex operator ++(){
real++;
return *this;
} //pre
Complex operator ++(int){
Complex b;
b.real = real , b.imag = imag;
real++;
return b;
} //post
operator float(){
return real;
}
};
Complex operator +(float f , Complex & c){
Complex b;
b.real = c.real + f;
b.imag = c.imag;
return b;
}
Complex operator -(float f , Complex & c){
Complex b;
b.real = f - c.real;
b.imag = c.imag;
return b;
}
Complex addTo(float v , Complex c){
Complex b;
b.real = c.real + v;
return b;
}
class Stack{
int sz;
int *arr;
int top;
static int counter;
public:
Stack(int n = 10){
top = 0;
sz = n;
arr = new int[sz];
cout << "Stack is created\n";
counter++;
}
Stack(const Stack &tmp){
top = tmp.top;
sz = tmp.sz;
arr = new int[sz];
for(int i = 0 ; i < sz ; i++){
arr[i] = tmp.arr[i];
}
counter++;
cout << "is created\n";
}
int pop(){
if(top == 0){
cout << "Empty\n";
return -1;
}
return arr[--top];
}
friend void viewcontent(Stack tmp);
void push(int x){
if(top == sz){
cout << "stack is full\n";
return;
}
arr[top++] = x;
}
static int getCnt(){
return counter;
}
Stack& operator =(const Stack& s){
delete []arr;
top = s.top;
sz = s.sz;
arr = new int[sz];
for(int i = 0 ; i < sz ; i++){
arr[i] = s.arr[i];
}
return *this;
}
~Stack(){
delete[] arr;
counter--;
cout << "destroyed\n";
}
};
int Stack::counter = 0;
void viewcontent(Stack tmp){
int index = tmp.top;
while(index){
cout << tmp.arr[--index] << '\n';
}
}
int main() {
Complex c1 , c2(5) , c3(2 , 3);
c1.setReal(3);
c1.setImag(4);
cout << c1.getImag() << '\n';
c2.print() ;
c1.print() ;
c1 = c2 + c3;
c1.print();
c1 = c2 +(float)5;
c1.print() ;
c1 = (float)5 + c2;
c1.print() ;
c1 = c2 - c3;
c1.print();
c1 = c2 -(float)5;
c1.print() ;
c1 = (float)5 - c2;
c1.print() ;
c1++;
c1.print();
cout << (float)c1 << '\n';
return 0;
}
//=========================================OOP===================================================//
//========================================This===================================================//
/*
class stud{
int id;
public:
stud(){}
void print(){
cout << this << '\n' << id << '\n';
}
stud(int id){
id = id; // now because the parameter that i am passing to the constructor has the same name as the attribute
// it will assign the parameter to itself so to avoid this thing we use "this"
this->id = id; // now the compiler understands that i mean the private member id
}
};
-->main
// "this" is a pointer that points to the object that called the function
stud a , b , c(10);
a.print();
b.print();
c.print();
*/
/*=============================binary operator overloading========================================//
class sum{
int x , y;
public:
sum(int i = 0 , int j = 0){
x = i , y = j ;
}
void getdata(){
cout << "Enter x\n";
cin >> x ;
cout << "Enter y\n";
cin >> y ;
}
void print(){
cout << x << ' ' << y << '\n';
}
// now to add to objects we need to create a member function that do this
void add(sum c1 , sum c2){
x = c1.x + c2.x ;
y = c1.y + c2.y;
}// this is the basic function
sum add1(sum c2){
sum c3 ;
c3.x = x + c2.x ;
c3.y = y + c2.y;
return c3 ;
}// using '='
//now using operator overloading
sum operator+(sum c2){// this can be done with every operator
sum c3 ;
c3.x = x + c2.x ;
c3.y = y + c2.y;
return c3 ;
}
};
--> main
sum c1 , c2(1 , 2) , c3;
c1.getdata();
//c3.add(c1 , c2); // basic
// now if i want to use the '=' i will create a function that returns an object
//c3 = c1.add1(c2);
// using operator overloading
c3 = c1 + c2;
// it is the same as this
c3 = c1.operator+(c2);
c3.print();
*/
/*=========================================friend class===================================================//
class square;
class rectangle{
int w , h ;
public:
int area(){
return w*h ;
}
//friend class square; // i cant do this as i have to make it in the square function not here
void convert(square);// to use the square class i have to make these two classes friends
};
class square{
int side;
public:
void s(int x){
side = x;
}
friend class rectangle;
};
void rectangle::convert(square s){
w = h = s.side;
}
--> main
square sqr ;
rectangle rect;
sqr.s(4);
rect.convert(sqr);
cout << rect.area();
*/
/*=========================================friend fucntion===================================================//
class myclass{
int a , b ;
public:
myclass(int i , int j );// this is a member of this class but it is a prototype
friend int sum(myclass ob);// how to make a friend function
// and it is not a member of this class
};
myclass::myclass(int i , int j){// this is a member of the class but defined outside it
a= i , b = j;
}
int sum(myclass ob){
return ob.a + ob.b;// why i made a friend function to access the private attributes in it
}
class A;// class prototyping
class B;
// if i want to add two variables but they are not in the same class
class A{// here i access the class
private:
int x , y;
public:
A(int i , int j ){// constructor to intialize attributes
x = i , y = j;
}
friend int fun(A a , B b);// making fun a friend of class A
};
class B{
private:
int x , y;
public:
B(int i , int j ){
x = i , y = j;
}
friend int fun(A a , B b);// same thing here
};
int fun(A a , B b){// now we can access private attributes as this function is a friend of both a and b
return a.x + b.x ;
}
--> main
myclass o(10 , 20);
cout << sum(o);
A a(5 ,5);
B b(5 , 5);
cout << fun(a , b);
*/
/*=========================================const===================================================//
class Time{
int h , m , s ;
public:
void print()const // this is how to declare a const function
{
cout << h << ' ' << m << ' ' << s << '\n';
}
Time(int h1 , int m1 , int s1){
h = h1 , m = m1 , s = s1;
}
};
--> main
const Time noon(12 , 0 , 0);
noon.print();
// when i initalize an object of type const then i can reach only the const functions inside it
// but when i intialize it the normal way then i can access any function inside it
*/
/*=========================================static===================================================//
void f(){
static int x =0; // when i type static so whenever i call this function the value of x would be updated
// like if i called this function 3 times first the val of x would be 1 then i call it again the value
// of x wont be 0 but it will remain 1 and then update it to 2 and so on
x++;
cout << x << '\n';
}
class student{
static int count ;
string name ;
int id ;
public:
static void print(){ // static here make me able to call this function in two ways
// first way is the way we know
// second one will be shown below
cout << count << '\n';
}
student(){
count++;
name = "no name";
id = 0;
cout << count << ' ' << name << ' ' << id << '\n';
print();
}
};
int student::count = 0;// to give initial value to a static member in the class
--> main
student s1 , s2;
student s3[3];
// i can call the print function like this
s1.print();
// or like this;
student::print();
*/
/*=========================================enum===================================================//
enum days {sat = 1, sun , mon , tue , wend , thur , fri};
// when we print any day from here it will be printed as a number like sat will be printed as 0
// first element starts at 0
// if i wanted the first element to start from 1 then ill put sat = 1
// they are const values cannot be changed and cant be taken from input
--> main
days m[7] = {sat , sun , mon , tue , wend , thur , fri};
for(int i = 0 ; i < 7; i++)cout << m[i] << '\n';
// this is how to deal with the enum
*/
//=========================arr of objects and pointer to object==================================//
/*
class student{
string name ;
int id;
public:
student(){ // empty constructor
cout << "empty\n";
id = 0 , name = "no name";
}
student(string n , int i){
cout << "para\n";
name = n , id = i ;
}
void print(void){
cout << name << ' ' << id << '\n';
}
};
--> main
int arr[5] = {10 , 23 , 45 , 32 , 11};
cout << arr << '\n'; // arr is a pointer pointing to the first element in the array
// notice that it is a constant pointer so that i cant change its value
//arr++; // this is wrong
// but if i want to print the next element i can simply say that
cout << (arr+1)<< '\n';
int* ptr ;
ptr = arr ; // now we made ptr points to the first element of the array
// and then i can access all elements of the array by this pointer
// and also i can use this
ptr++ , ptr-- , ptr+= 2 ; // this will make pointer move to the next element
student a("ahmed" , 123) , b("bate7a" , 412);
//student arr1[3] = {student("adek" , 421)}; // array of objects
// now the first object will call the parametarized constructor and others will call the empty one
student arr1[3] = {a , b};// now we give the array objects so it will only call the constructor
// when a , b are first initialized and will call the empty constructor for the third object
// now lets create a pointer of type student to point to the array
student *p;
p = arr1;
for(int i = 0 ; i < 3 ; i++){
arr1[i].print();
// to print the arr1 elements using pointer we do this
//(p+i)->print();
// or
p++->print();
}
*/
/*=========================================new_delete===================================================//
class rectangle{
int* ptrr , *ptrr1 ;
public:
rectangle(int ,int);
~rectangle();
int print(){
return (*ptrr * *ptrr1) ;
}
};
rectangle::rectangle(int a , int b){
ptrr = new int ;
ptrr1 = new int;
*ptrr = a , *ptrr1 = b ;
}
rectangle::~rectangle(){
delete ptrr ;
delete ptrr1;
}
--> main
void* ptr ; // i can declare a void ptr that can be linked to any data type
int *ptr1 ;
ptr1 = new int ;
// this make the compiler give the poitner a new address to use ;
*ptr1 = 10 ;
cout << ptr1 << ' ' << *ptr1 << '\n';
// now after we finish using the pointer we have to delete it (format it __ pointer actually still exist)
delete ptr1;
// now u can reuse the pointer with another address
ptr1 = new int;
*ptr1 = 10;
cout << ptr1 << '\n'; // this prints the location of the pointer
cout << &ptr1 << '\n'; // this prints the location the compiler gave me for the new int
cout << *ptr1 << '\n'; // this prints the value
delete ptr1 ;
// new and delete with class
rectangle recta(3 , 5) , rectb(4 , 6);
cout << recta.print() << '\n';
cout << rectb.print() << '\n';
*/
/*=========================================struct===================================================//
struct car{
string name , color ;
int speed , model;
}g , k;// a way to declare a struct
struct exam{
double first , second , final;
// i can also write functions in here
void p(){
cout << "struct\n";
}
};
class subject{
private:
string name ;
exam Exam;
public:
subject(){
name = "no name";
Exam = {0 , 0 ,0}; // this can happen only when i give the struct initial value
}
subject(string nam1e , double fi , double se , double fin){
name = nam1e ;
Exam.final = fin , Exam.second = se , Exam.first = fi;
Exam.p();
}
double tot(){
return Exam.final + Exam.first + Exam.second;
}
void print(){
cout << tot() << '\n';
// if i want to print anything else
}
};
--> main
g = {"ss" , "sq" , 22 , 23};
cout << g.speed << '\n'; // thats how to initialize a struct and access element in it
// how to compare a struct i cant say if(k>g) cant compare the whole struct
// but i can compare every element with another element
if(g.speed < g.model)cout << 1 << '\n'; // i can also compare to elements from the same struct
// to deal with functions we can simply say that the struct is like int or long long and can use it as i want in functions
// how to combine struct with class
subject e("OOp" , 24 , 34 , 350);
e.print();
*/
/*=========================================destructor===================================================//
// the same name as the class
// starts with (~)
// doesnt have params and doesnt retrun anything
// a class has only one destructor
// deletes dynamic object from the memory
// deletes the objects from bottom to top
// will be called when the right brace closes
class rectangle{
private:
int W , H ;
public:
// if there is param constructor so i have to create the object with params
// if i dont want to create an object with params then i have to put the empty constructor to avoid errors
rectangle(int a , int b):W(a) , H(b)// i can set attributes this way
{
cout << "A rectangle has been created\n";
// i can create an object here too
}
~rectangle(){
cout << W << ' ' << H << '\n';
cout << "A rectangle has been deleted\n";
}
};
// another example on how we can use functions
class phone{
// i dont have to use private here
string name , model;
int price;
public:
phone(string a , string b , int p):name(a) , model(b) , price(p)
{// i have to put braces here
cout << "Phone\n";
}
void print();// i can type the prototype of the function here and complete it anywhere
// i can also type a prototype of destructor here
~phone();
};
// like here but i must type the class name with scope resolution
phone::~phone(){
cout << "object has been destroyed\n";
}
void phone::print(){
cout << name << ' ' << model << ' ' << price << '\n';
}
class student{// example
string name ;
int id;
public:
student(){
cout << "object created\n";
}
student(string s , int a)
{ name = s , id = a ;
cout << "object created\n";
}
void set_name_id(string s , int a ){
name = s , id = a;
}
~student(){
cout << "object destroyed\n";
}
void print(){
cout << name << ' ' << id << '\n';
}
};
void f(student& s){
student s1;
s1 = s;
s.set_name_id("sami" , 12345);
s.print();
s1.print();
}
--> main
rectangle R1(3 , 4) , R2(4 , 6);
phone("sam" , "any" , 15);
student st1("ahmed" , 1111) , st2("moh" , 22222);
cout << "going to function\n";
f(st1);
cout << "back from function\n";
st1.print();
*/
/*========================================constructor=================================================//
// have the same name as the class
// dont return any value even void
// when an object is created the constructor is called immediately
class triangle{
private:
double base , height;
public:
// empty constructor
triangle(){// thats how we define empty constructor it is called when an object is created
cout << "first constructor\n";
// we can also use constructor to give initial values to the attributes
base = 0 , height = 0;
}
// parameterized constructor we can use it as a set function to set only initial values
triangle(int b , int h ){//there is at least one parameter in it
base = b , height = h;
cout << "parameterized constructor\n";
}
//overloading constructor
triangle(int b){// this is made to set only the base value
// so when i dont input the height it will get here not the previous one
// and if i give the parameter h initial value in the constructor above it will be error
base =b ;
}
void setBase_height(double b , double h){
base = b , height = h;
}
double area(){
return 0.5*base*height ;
}
void print(){
cout << base << ' ' << height << ' ' << area() << '\n';
}
};
// copy constructor example
class Copy{// we use copy constructor when we have a lot of attributes
private:
int a1 , a2 , a3 ,a4 , a5 , a6 , a7 , a8;
public:
int x ; // i can create variables in public and can access them in main
Copy(int aa1 , int aa2 , int aa3 , int aa4 , int aa5 , int aa6 , int aa7 , int aa8)
{
a1 = aa1 , a2 = aa2 , a3 = aa3 , a4 = aa4 , a5 = aa5 , a6 = aa6 , a7 = aa7 , a8 = aa8 ;
}
// instead of doing the param constructor we can do a copy constructor by passing a class to it
Copy(const Copy& a){// to pass a class we have to type it like this
a1 = a.a1 , a2 = a.a2 , a3 = a.a3 , a4 = a.a4 , a5 = a.a5 , a6 = a.a6 , a7 = a.a7 , a8 = a.a8;
// here iam able to use the private attributes of the constructor
// but in main i cant i only can use the public functions
// we cant use public functions or attributes in here
}
void print(){
cout << a1 << ' ' << a2 << ' ' << a3 << ' ' << a4 << ' ' << a5 << ' ' << a6 << ' ' << a7 << ' ' << a8 << '\n';
}
};
--> main
// now if we create an object the constructor will start and print the message inside
triangle ob; // if i added more objects constructor will start (number of objects)times
triangle ob1(5 , 10); // now it wont call the empty constructor it will call the parameterized one
ob1.print();
//if i wanted to edit the values of the attributes i will use the set function
ob1.setBase_height(5 , 10);
//if there is more than one constructor it will only call one of them
// how to use copy constructor
Copy g(1 , 2 , 3 , 4 , 5 , 6 , 7 ,8);
g.print();
// now to pass an object
Copy h(g);
h.print();
h.x = 5;// how to access public variables in a class
cout << h.x ;
*/
//========================================class=================================================//
/* functions
class car{// to create a class we type(class , class name)
private: // here we type the attributes of the class , we cant access this attributes in main
string name;
char color[15];
int maxspeed;
int model;
public: // here we type the functions that can access the attributes of the class
void setName(string n){
name = n;
}
void setColor(char n[]){
strcpy_s(color , n);
}
void setMaxspeed(int m){
maxspeed = m;
}
void setModel(int m ){
model = m;
}// these are functions to set the variables
string getName(){
return name;
}
char* getColor(){// here we typed (*) so that the return type will be array of chars
return color;
}
int getMaxspeed(){
return maxspeed;
}
int getModel(){
return model;
}// these are all functions to get the attribute
void print(){
cout << name << ' ' << color << ' ' << maxspeed << ' ' << model << '\n';
}// to print the attributes
};
// another example
class triangle{
private:
double base , height;
public:
void setBase_height(double b , double h){
base = b , height = h;
}
double getBase(){
return base;
}
double getHeight(){
return height;
}
void print(){
cout << base << ' ' << height << '\n';
}
};
using classes in main
// to access a class we should create an object with the class type
car x ;// now we created an object with type car which has all the functions in the class
// to access the functions we type (varName.)then we get all the functions in the class
// anything typed in the class is called a member --> member private , member function
x.setColor("black");
x.setMaxspeed(300);
x.setModel(2015);
x.setName("BMW");
x.print();
cout << x.getMaxspeed() << '\n';
triangle xyz ;
xyz.setBase_height(14.0 , 13.2);
*/
// pointers
/* Using poitners to access single values
int i = 16;
int* ptr ; // * is for declaring that this var is a pointer
ptr = &i; // & is for getting the address of i
cout << ptr << ' ' << *ptr << ' ' << i << '\n'; // printing address , value , * is dereference operator
*ptr += 5; // if i want to access the value of the address use the derefernce operator
cout << *ptr << ' ' << i ; // the change happens in i too
*/
//===============================================================================================//
/*
char msg[] = "Hello"; // making array of chars and notice that the name of the array is a pointer pointing to the first char(address) of the array
// so now if i said cout << msg << ' ' << *msg ; it will print the whole string and the first address value
// also the array looks like 'H' , 'e' , 'l' , 'l' , 'o' , '\0'-->means that the array ends here called null
// the name of the array is constant pointer meaning that i cant point to anywhere else except the array itself
char* ptr ; // now we declare a pointer char type
ptr = msg; // why i didnt put & before msg bec we said that msg is actually a pointer
*ptr = 'M'; // now the first char of the array is changed to M
cout << *msg << '\n' ; // will print the first char after being changed
cout << ptr << ' ' << *ptr << '\n' ; // print the whole array from the address of the pointer to the end of the string and value before changing
ptr++ ; // now when using ++ or -- or += or whatever it will change the address of the pointer
// by moving it to the next address
// for example if we say ptr points to 3000(address) so because it is of char type it will be 3001
// but if it is of int type it will be 3004 so it actually adds up the index*(size of data type) to the address
*ptr = 'a' ; // now second char equals a
cout << ptr << ' ' << *ptr ; // printing the string from (ptr to end) and value after changing
cout << '\n' << &ptr ; // thats if i wanted to print the address of the element iam on now
*/
//===============================================================================================//
/*
int arr[] = {1 , 2 , 3 , 4 , 5};
cout << *arr << '\n'; // printing first element in the array
cout << arr << '\n'; // printing the address of the first element in the array
// note that it doesnt print the whole array as the array of chars
for (int i = 0; i < 5; i++)
{
cout << *(arr+i) << ' ' ;// here we can access the elements of the array by using the array name as a
// pointer to the first element of the array and then moving it by the value of i
}
for(int i = 0 ; i < 5 ; i++)
cout << arr+i << ' '; // now we print all the addresses of the array
*/
//===============================================================================================//
/*
//int* y = &5 ; // this is invalid because iam not giving it an address of a variable
//swap(5 , 5); // also invalid if passing it be reference or pointer
int x = 5 , y = 8 ;
void swap(int& x , int& y){ // passing by reference
int tmp = x ; // here we just pass the address so that every change applied here well be applied to the variables
x = y ;
y = tmp ;
}
void swap(int* ptr1 , int* ptr2){ // passing by pointer
int tmp = *ptr1 ; // here using * is a must because we are using pointers
*ptr1 = *ptr2 ;
*ptr2 = tmp ;
}
swap(x , y);
cout << x << ' ' << y << '\n';
int* ptr1 = &x ;
int* ptr2 = &y ;
swap(ptr1 , ptr2);// we can use it like this or --> swap(&x , &y); as we are passing addresses
cout << *ptr1 << ' ' << *ptr2 ;
*/
//===============================================================================================//