Thursday, June 29, 2017

Simple Array Class Template

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It is an implementation of a simple array class template.  For any questions  and discussion use the comment section below.*/

#include <iostream>

using namespace std;

template<typename T>
class Array{private:
        T* parray;
        int size;

        public:
        Array():parray(NULL),size(0){};
        Array(int sz):parray(new T[sz]),size(sz){};
        Array(T* parr,int sz):parray(new T[sz]),size(sz){for(int i=0;i<size;i++){parray[i]=parr[i];}}
        void printarray(){cout<<"[ "; for(int i=0;i<size;i++){cout<<parray[i]<<' ';} cout<<']'<<endl;}
        T getelement(int i){return parray[i];}
        void setelement(int i,T telem){parray[i]=telem;}
        void copyarray(Array<T> art){delete []parray; parray=new T[art.size]; size=art.size; for(int i=0;i<size;i++){parray[i]=art.getelement(i);}}
        ~Array(){delete []parray;}
};

int main(){

Array<int> ia(10);
ia.printarray();

float finita[5]={1,2,3,4,5};

Array<float> fa1(finita,5);

fa1.printarray();

Array<float> fa2;
fa2.copyarray(fa1);
fa2.printarray();
}

Wednesday, June 21, 2017

Variations on Templates

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It offers variations on the template theme and their implications. The classes used here are not necessarily useful, as they were designed for the sole purpose of offering a synoptic peek at the template syntax.  For any questions  and discussion use the comment section below.*/

#include <iostream>

using namespace std;

class AA{public: int data1; double data2;};
class BB{public: int data1; double data2;};

template<typename T1,typename T2>
class BoxOf2{private:
        T1 var1;
        T2 var2;
         public:
            double sum1(){return var1+var2.data1;}//The presence of this function dectates that T2 must have a public member variable called data1
        double sum2(){return var1+var2.data2;}//The presence of this function dectates that T2 must have a public member variable called data1
        T1 &getvar1(){return var1;}//We let get return a reference here to allow for left-hand-side assignment. See below. This consideration is not related to templates per se.
        T2 &getvar2(){return var2;}//We let get return a reference here to allow for left-hand-side assignment. See below. This consideration is not related to templates per se.
        void setvar1(T1 v1){var1=v1;}
        void setvar2(T2 v2){var2=v2;}                   
        };

int main(){

BoxOf2<int,AA> bia1; BoxOf2<int,AA> bia2; BoxOf2<float,AA> bfa; BoxOf2<int,BB> bib1; BoxOf2<int,BB> *pbib;//Box<int,AA> Box<float,AA>  Box<int,BB> are strictly different types. As such, they cannot be assign to each other nor cast to each other.

bia1.setvar1(10);
bia1.setvar2(AA());//Set var2 with an object of type AA. If they exist, parametrized constructors can be used here.
bia1.getvar2().data1=100;//This is possible because getvar2 returns a reference.
bia1.getvar2().data2=1000;//This is possible because getvar2 returns a reference.
cout<<bia1.getvar1()<<endl;
cout<<bia1.getvar2().data1<<endl;
cout<<bia1.getvar2().data2<<endl;

bia2=bia1;//bia1 and bia2 are of the same type this why they can be assigned to each other. They are both of type BoxOf2<int,AA>


pbib = new BoxOf2<int,BB>();//Example of using the new operator to create and object in the runtime.

bib1.setvar1(11);
bib1.setvar2(BB());//Set var2 with an object of type AA. If they exist, parametrized constructors can be used here.
bib1.getvar2().data1=111;
bib1.getvar2().data2=1111;
BoxOf2<int,BB> bib2(bib1);//Copy constructor.
*pbib=bib2;
cout<<pbib->getvar1()<<endl;
cout<<pbib->getvar2().data1<<endl;
cout<<pbib->getvar2().data2<<endl;

delete pbib; //delete as usual.

return 0;
}

The Diamond Problem & Virtual Inheritance

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It illustrates the solution of the diamond problem in C++ using virtual inheritance. For any questions  and discussion use the comment section below.*/
 
#include<iostream>

using namespace std;


class Bar
{
public:
    int k;
    void DoSomething() { k=10; }
};

class Foo : virtual public Bar
{
public:
    int h;
    void DoSpecific() { k=k+4; h=5; }
};

class Moo : virtual public Bar
{
public:
    int h;
    void DoSpecific() { k=k+4; h=5; }
};

int main(){Bar b1; Foo f1; Moo m1;

b1.DoSomething();
f1.DoSomething();
m1.DoSpecific();

cout<<b1.k;
return 0;
}

Data and Complexity Hiding

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It illustrates the concept of data hiding and complexity hiding. For any questions  and discussion use the comment section below.*/
 
#include <iostream>

using namespace std;

class Box{/* A box is assumed to be a rectangular cuboid. The box is also assumed to be of uniform thickness which includes the cover. Please keep in mind that this example is hypothetical and bears no affinity to the reality of determining box characteristics whatsoever.*/
private:
    double st;//Stiffness
    double den;//Density: 7.82 steel/
0.55 wood/0.7 cardboard
    int matid;//Material id: (1) cardboard (2) wood (3) steel
    double wd,dp,ht,tk;//width, depth, height, thickness
    double outervolume(){return wd*dp*ht;}
    bool impossiblebox(double w,double d,double h,double t){
                bool truthvalue;
                truthvalue=w>=0&&d>=0&&h>=0;
                truthvalue=truthvalue&&w>2*t&&d>2*t&&h>2*t;
                return !truthvalue;
                }
               
   

public:
    Box():st(0), den(0), matid(0), wd(0), dp(0),ht(0){}
    Box(int m,double w,double d,double h,double t){
        if(!impossiblebox(w,d,h,t)){
                matid=m; wd=w; dp=d; ht=h; tk=t;
                switch(m)
                {
                    case 1: st=0.5;den=1; break;
                    case 2: st=1.5;den=0.7; break;
                    case 3: st=2.9;den=0.1;
                }
                }
    }

    double capacity(){return (wd-2*tk)*(dp-2*tk)*(ht-2*tk);}

    double tare(){return (outervolume()-capacity())*den;}//The weight of an empty box is called: tare
   
    double maxLoad(){return st*tk*den*1.4;}
};


int main(){

Box b1(2,100,50,40,3);
Box b2(2,100,50,40,70);
cout << b1.maxLoad()<<' ';
cout << b2.maxLoad();

return 0;
}

Sunday, June 11, 2017

Operator Overloading III

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It illustrates the importance of implementing a const index operator. For any questions  and discussion use the comment section below.*/

#include <iostream>

using namespace std;

class Indexer{
    private:
    double a0,a1,a2,a3,a4;

    public:
  
    Indexer():a0(0),a1(0),a2(0),a3(0),a4(0){};  
    double& operator [](int index){
            if(index<=0){return a0;}
            else{
                if(index>=4){return a4;}
                else{
                    switch(index){
                      
                        case 1: return a1;
                        case 2: return a2;
                        case 3: return a3;
                        }
                    }
            }
        }

    const double& operator [](int index) const {
            if(index<=0){return a0;}
            else{
                if(index>=4){return a4;}
                else{
                    switch(index){
                      
                        case 1: return a1;
                        case 2: return a2;
                        case 3: return a3;
                        }
                    }
            }
        }
};

double sumelements(const Indexer idr){double sum=0; for(int i;i<5;i++){sum=sum+idr[i];}; return sum;}

int main(){
Indexer indr;

indr[0]=11; indr[1]=22; indr[2]=33; indr[3]=44; indr[4]=55;
double g=sumelements(indr);//Compilation error if const index operator is not implemented because sumelements will attempt to use a const index operator

const Indexer cindr;
double h=cindr[0];//Compilation error if const index operator is not implemented because cinder is const.


return 0;
}

Multiple Inheritance

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It shows one important use of multiple inheritance. For any questions  and discussion use the comment section below.*/
 
#include <iostream>

using namespace std;

class Food{};
class Wild{};


class Bird{ public: double eggsize;
            virtual void sound(){cout<<"Sound";}//It is essential to have a virtual function here for dynamic_cast<> to work.
};

class Chicken:public Bird, public Food{};
class Parrot:public Bird, public Wild{};
class Pheasant:public Bird, public Wild, public Food{};   





int main(){
const int BN(6);
Bird *b1[BN];

b1[0]=new Parrot();
b1[1]=new Chicken();
b1[2]=new Chicken();
b1[3]=new Pheasant();
b1[4]=new Parrot();
b1[5]=new Pheasant();

for(int i=0; i<BN; i++){if(dynamic_cast<Food*>(b1[i])!=NULL){cout<<i<<" is edible."<<endl;}}
for(int i=0; i<BN; i++){if(dynamic_cast<Wild*>(b1[i])!=NULL){cout<<i<<" is wild."<<endl;}}

for(int i=0; i<BN; i++){delete b1[i];}
return 0;}

Operator Overloading II

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It illustrates input, output, and typecasting operator overloading, as well as forward declaration & postponed implementation. For any questions  and discussion use the comment section below.*/
 
#include<iostream>

using namespace std;

class Cents;//Forward declaration of class Cents

class Dollars{
    private:
        double amount;
    public:
        Dollars():amount(0){};
        Dollars(double am):amount(am){};
        operator double(){return amount;}//Opposite conversion from basic types is not possible
        operator Cents();//Only prototype is possible here, since class Cents definition is incomplete at this stage. We will have to write this operator's implementation after class Cents.
        friend ostream& operator <<(ostream &, Dollars);
        friend istream& operator >>(istream &,Dollars &);
    };

ostream& operator <<(ostream &out, Dollars d){
            out<<'$'<<d.amount;
            return out;
            }

istream& operator >>(istream &in,Dollars &d){ in>>d.amount; return in;}//Input operator has not been covered in this term.

class Cents{
    private:
        double amount;
    public:
        Cents():amount(0){};
        Cents(double am):amount(am){};
        operator double(){return amount;}//Opposite conversion from basic types is not possible
        operator Dollars(){return Dollars(amount/100);}
        friend ostream& operator <<(ostream &, Cents);
        friend istream& operator >>(istream &,Cents &);
    };

ostream& operator <<(ostream &out, Cents c){
            out<<c.amount;
            return out;
            }

istream& operator >>(istream &in,Cents &c){ in>>c.amount; return in;}

   
Dollars::operator Cents(){return Cents(amount*100);}


int main(){
Dollars d1(5.3221),d2;

cout<<d1<<endl;
cout<<d1<<endl;

Dollars d3,d4;
d3=d4;

cout<<d3<<endl;

cout<<d1<<endl;
cin>>d3>>d4;
cout<<d3<<' '<<d4<<endl;

Cents c1(400),c2;
c2=d3;

cout<<c1<<' '<<c2<<endl;
d4=c1;
cout<<d4;

return 0;
}

Saturday, June 10, 2017

Operator Overloading I

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. It uses operator overloading to implement vector addition, subtraction, negation, and scaling. For any questions use the comment section below.*/

#include<iostream>
#include<stdlib.h>
#include<cmath>

using namespace std;

const double pi=3.14159;

class Vec{
private:
    double magnitude;
    double angle;
public:
//Accessor and mutator member functions go here.
    Vec(){magnitude=0; angle=0;}
    Vec(double mag,double angle):magnitude(mag),angle(angle){};
   
    Vec operator+(Vec vright){double xleft, yleft, xright, yright, newmag, newang;
                    xleft=magnitude*cos(angle);
                    yleft=magnitude*sin(angle);
                    xright=vright.magnitude*cos(vright.angle);
                    yright=vright.magnitude*sin(vright.angle);
                    newmag=sqrt(pow(xleft+xright,2)+pow(yleft+yright,2));
                    newang=asin((yleft+yright)/newmag);
                    return Vec(newmag,newang);}
    Vec operator-(Vec vright){return *this+Vec(vright.magnitude,vright.angle+pi);}
    Vec operator-(){return Vec(magnitude,angle+pi);}
    friend Vec operator*(double,Vec);
    friend Vec operator*(Vec,double);
    void show(){cout<<magnitude<<' '<<angle<<'\n';}
    };

Vec operator*(double scalar,Vec vr){return Vec(scalar*vr.magnitude,vr.angle);}
Vec operator*(Vec vl,double scalar){return Vec(scalar*vl.magnitude,vl.angle);}

int main(){

Vec v1(4,0), v2(3,pi/2);
Vec v3;

v1.show(); v2.show();
(v1+v2).show();
(v2+v1).show();

(v1+(-v2)).show();
(v1-v2).show();

v3=-v1+v2-3*v1+1.7*v2+v2*2.3;

v3.show();

(-v3).show();

(3.4*v3*2.3).show();

return 0;
}



Deep Classes Proper Design

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. The code is a model answer to a Spring-2017 2nd exam question. For any questions use the comment section below.*/

#include <iostream>

using namespace std;

class AA{public: int d,e;};

class BB{public: int f,g;
    AA *a;
    BB(){a=new AA();}
    BB(const BB& b){a=new AA(*b.a);}
    ~BB(){delete a;}
    BB& operator=(BB b){ f=b.f; g=b.g; *a=*b.a; return *this;}
};

class CC{public: int h,i;
    BB *b;
    CC(){b=new BB();}
    CC(const CC& c){b=new BB(*c.b);}
    ~CC(){delete b;}
    CC& operator=(CC c){ h=c.h; i=c.i; *b=*c.b; return *this;}
    };

Uglyclass and Its Wrapper

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. The code is a model answer to a Spring-2017 2nd exam question. For any questions use the comment section below.*/

#include <iostream>

using namespace std;

class Uglyclass{public:
int x1, x2, x3, x4, x5, x6;
};

class Wrapper{
    private:
    Uglyclass uc;

    public:
   
    int& operator [](int index){
            if(index<=1){return uc.x1;}
            else{
                if(index>=6){return uc.x5;}
                else{
                    switch(index){
                       
                        case 2: return uc.x2;
                        case 3: return uc.x3;
                        case 4: return uc.x4;
                        case 5: return uc.x5;
                        }
                    }
            }
        }
};

int main(){
Wrapper w;

w[0]=2; w[2]=3; w[3]=4; w[4]=5; w[5]=6; w[7]=8;

for(int i=0; i<6; i++){cout<<w[i];}
return 0;
}

Wednesday, June 7, 2017

Bubbles

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. The code is a model answer to a Spring-2017 2nd exam question. For any questions use the comment section below.*/

#include <iostream>
#include <cmath>

using namespace std;

const long double ldPI = 3.141592653589793238L;

class Air{
public:
 double quant;
 Air():quant(0){};
 Air(double q){quant=q;}
};


class Bubble{
    private:
    const double minthickness;// = 10;
    const double maxthickness;// = 1000;

    double matam;//material amount
    Air airam;

    double innerradius(){return pow(airam.quant*3.0/(4.0*ldPI),1.0/3.0);}
    double outerradius(){return pow((airam.quant+matam)*3.0/(4.0*ldPI),1.0/3.0);}

   

    bool impossibleBubble(){return thickness()>maxthickness||thickness()<minthickness;};
   
    void burst(){airam=0; matam=0;}
   
    public:

    double thickness(){return outerradius()-innerradius();}
    double getMatam(){return matam;}
    double getAir(){return airam.quant;}

    Bubble():minthickness(10), maxthickness(1000), matam(0), airam(Air()){};
    Bubble(double m, Air a):minthickness(10), maxthickness(1000), matam(m), airam(a) {if(impossibleBubble()){burst();}}

    Bubble operator+(Bubble b){double ml=matam+b.matam; double airl=airam.quant+b.airam.quant; return Bubble(ml,Air(airl));}
    Bubble operator+(Air a){double airl=airam.quant+a.quant; return Bubble(matam,Air(airl));}
    Bubble operator*(double factor){double airl=airam.quant*factor; return Bubble(matam,Air(airl));}

    Bubble &operator=(Bubble b){matam=b.matam; airam=b.airam; return *this;}
};

int main(){

Bubble b1(1e8, Air(10));
Bubble b2(0.5e8,Air(6));
Bubble b3;

Air a1(200);

b3=b1+b2;

cout<<b1.thickness()<<'\n';
cout<<b2.thickness()<<'\n';
cout<<b3.thickness()<<'\n';

cout<<b1.getMatam()<<'\n';
cout<<b2.getMatam()<<'\n';
cout<<b3.getMatam()<<'\n';


cout<<b1.getAir()<<'\n';
cout<<b2.getAir()<<'\n';
cout<<b3.getAir()<<'\n';

b1=b1+a1;

cout<<b1.thickness()<<'\n';
cout<<b2.thickness()<<'\n';
cout<<b3.thickness()<<'\n';

cout<<b1.getMatam()<<'\n';
cout<<b2.getMatam()<<'\n';
cout<<b3.getMatam()<<'\n';


cout<<b1.getAir()<<'\n';
cout<<b2.getAir()<<'\n';
cout<<b3.getAir()<<'\n';

b3=b3*2;

cout<<b1.thickness()<<'\n';
cout<<b2.thickness()<<'\n';
cout<<b3.thickness()<<'\n';

cout<<b1.getMatam()<<'\n';
cout<<b2.getMatam()<<'\n';
cout<<b3.getMatam()<<'\n';


cout<<b1.getAir()<<'\n';
cout<<b2.getAir()<<'\n';
cout<<b3.getAir()<<'\n';
}

Overloading Across Inheritance Lines

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. The code illustrates function overloading across inheritance lines in C++. For any questions use the comment section below.*/

#include<iostream>
#include<stdlib.h>

using namespace std;

class Base{public:int k;
    Base():k(rand()){};
    virtual void foo(double j){ cout<<"BASE foo(double)\n";}
    virtual void foo(int j){ cout<<"BASE foo(int)\n";}
    virtual void foo(){ cout<<"BASE foo()\n";}
    virtual ~Base(){};
};

class Der:public Base{public:
    using Base::foo;
    void foo(){cout<<"DER foo()"<<'\n';}
    };

class Chi:public Base{public:
    using Base::foo;
    void foo(double k){cout<<"CHI foo(double)"<<'\n';}
    void foo(){cout<<"CHI foo()"<<'\n';}
    };


int main(){
    Base *a[20];


for(int i=0;i<20;i++){
    switch(rand()%2){
        case 0: a[i]=new Der(); break;
        case 1: a[i]=new Chi();
        }
}

for(int i=0;i<20;i++){ a[i]->foo(1);}//behaves polymorphically, overloded
for(int i=0;i<20;i++){ a[i]->foo(1.1);}//behaves polymorphically, overloded

for(int i=0;i<20;i++){ delete a[i];}
return 0;
}

Inheritance & Polymorphism

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. The code illustrates inheritance and polymorphism in C++. It uses a necklace with several types of beads as an example. For any questions use the comment section below.*/

#include <iostream>
#include <cmath>
#include <stdlib.h>
using namespace std;

class Bead{
    protected:
    const double density;
    public:
    virtual double weight()=0;
    virtual void show(){cout<<"-B";}
    Bead(double D):density(D){};

    virtual ~Bead(){};
    };

class SBead:public Bead{
    private:
    double r;//radius
    public:
    double weight(){return (4/3*3.14159*r*r*r*density);}
    void show(){cout<<"-S";}
    void setR(double R){r=R;}
    SBead(double R,double D):r(R),Bead(D){};
    };

class CBead:public Bead{
        private:
        double s;//side length
        public:
        double weight(){return s*s;}
        void show(){cout<<"-C";}
        void setS(double S){s=S;};
        CBead(double S,double D):s(S),Bead(D){};
        };

class CyBead:public Bead{
        private:
        double r;//radius
        double h;//height
        public:
        double weight(){return r*r*h*3.14159;}
        void show(){cout<<"-Z";}
        void setRH(double R, double H){r=R;h=H;};

        CyBead(double R,double H, double D):r(R),h(H),Bead(D){};
        };

int main(){
Bead *bds[25];Bead *b;

for(int i=0;i<25;i++){
switch (rand()%3){
case 0: bds[i]=new  SBead(10,1.5); break;
case 1: bds[i]=new  CBead(10,1.5); break;
case 2: bds[i]=new  CyBead(10,5,1.5);}
}

for(int i=0;i<25;i++){bds[i]->show();}

return 0;
}

Function overloading

/*This code was written by A. El-Gadi of Tripoli University for educational purposes. The code illustrates function overloading in C++. It uses the several ways of determining a triangle as an example. For any questions use the comment section below.*/

#include<iostream>
#include<cmath>
using namespace std;

class Angle{public: float ang;};

class Triangle
{
public:
float a,b,c;
float area();
float perimeter();
void setSides(float s1,float s2,float s3){a=s1;b=s2;c=s3;}//SSS
void setSides(float s1,Angle alpha,float s2){a=s1;b=sqrt(s1*s1+s2*s2-s1*s2*cos(alpha.ang));c=s2;}//SAS
void setSides(Angle alpha,float s,Angle beta){a=s*sin(alpha.ang)/sin(beta.ang);c=s;b=s*sin(beta.ang)/sin(alpha.ang);}//ASA
void setSides(Angle alpha,Angle gamma,float s){
float beta;
beta=3.14159-alpha.ang-gamma.ang;
a=s*sin(alpha.ang)/sin(beta);c=s;b=s*sin(beta)/sin(alpha.ang);}//AAS
void setSides(float s,Angle alpha,Angle gamma){setSides(alpha,gamma,s);}//SAA
};

float Triangle::area(){
float s=(a+b+c)/2;

return sqrt(s*(s-a)*(s-b)*(s-c));
}

float Triangle::perimeter(){return a+b+c;}


int main(){

Triangle tSSS,tSAS,tASA,tAAS; Angle alpha,beta;

alpha.ang=0.7; beta.ang=3.14159/7;

float a,b,c;

a=10;
b=15;
c=20;

tSSS.setSides(a,b,c);
tSAS.setSides(a,alpha,c);
tASA.setSides(alpha,a,beta);
tAAS.setSides(alpha,beta,b);

cout<<tSSS.area()<<endl;
cout<<tSAS.area()<<endl;
cout<<tASA.area()<<endl;
cout<<tAAS.area()<<endl;


return 0;
}