Template Method and template class example in C++ Linux

How to use template in C++:
Template is mechanism in C++ to generate family of
 generic classes and generic functions that works with
different types of data types hence eliminate duplicate
 program for different data types and make the program
 more manageable and easier.
C++ Program for 1 argument template class
#include<iostream.h>
#include<string.h>
template <class T>
class test
{
T t;
public:
test(T x)//will work with int, float,char,string
{
t=x;
}
 void show(void)
 {
  cout<<"t= "<<t<<endl;
 }
};
//void test< T>::show(void)
//{
//cout<<"t"<<t<<endl;
//}
int main()
{
test<int>t1(10); //calls int version of test(T t)
t1.show();
test<float>t2(1.0);  //calls float version of test(T t)
t2.show();
test<char>t3('m');   //calls char version of test(T t)
t3.show();
test<char *>t4("HelloTemplate"); // calls string version of test(T t)
t4.show();
return 0;
}
C++ Program for 1 argument template function

#include<iostream.h>
//using namespace std
template <class T>
void display(T a)
{
cout<<a<<endl;
}
int main()
{
display(10);
display(20.12);
display('M');
display("MamaMeaa");
return 0;

}
 
//Template method example
#include<iostream>
using namespace std;
template<typename T1, typename T2>
void add(T1 a, T2 b)
{
    cout<<"\nSum : "<<a+b<<endl;
}

template<typename T3, typename T4>
T3 addSameAndReturn(T3 a, T4 b)//T1 T1
{
return a+b;
}
int main ()
{
    add(4,5.5454);//9.5454
    //specify types while passing values to funcion
    add<int,double>(4,5.5454);//9.5454
    add<float,int>(4.7,5); //9.7
    add<string,string>("hi","bye");//hibye

cout<<"addSameAndReturn(10.2,10.3)="<<addSameAndReturn(10.2,10.3)<<endl;//20.5
cout<<"addSameAndReturn(10,10.3)="<<addSameAndReturn<int,float>(10,10.3)<<endl;//20
cout<<"addSameAndReturn(10,10.3)="<<addSameAndReturn<float,int>(10.3,10)<<endl;//20.3

    return 0;
}

Pthread example code in C++ with and without synchronization

//Thread example in C++. One thread should prints odd numbers and the other thread should print the even numbers. Example without synchronization.
#include<iostream>
using namespace std;
int count=0; //global variable accessed by two threads
int maxx=10;
void* even(void *v)
{
cout<<"even thread"<<endl;
while(count<maxx)
{
if((count%2)==0)
{
cout<<count++<<" ";
//count++;
}
}
pthread_exit(0);//pthread_exit is called from the thread itself to terminate its execution (and return a result) early.
}
void* odd(void *o)
{
cout<<"odd thread"<<endl;
while(count<maxx)
{
if((count%2)==1)
{
cout<<count++<<" ";
//count++;// then proper order :)
}
}
pthread_exit(0);
}

int main()
{
pthread_t t1;
pthread_t t2;

pthread_create(&t1,NULL,&even,NULL);
pthread_create(&t2,NULL,&odd,NULL);
pthread_join(t1,0);
pthread_join(t2,0);
//pthread_join is called from another thread to wait for a thread to terminate and obtain its return value
cout<<endl;
return 0;
}
//OUTPUT
~$ g++ test1.cpp -lpthread
~$ ./a.out
even thread
0 odd thread
1 3 2 5 4 76  89 
//Improved Example synchronized using mutex and conditional variable.
#include<iostream>
using namespace std;
int count=0;
int maxx=10;
pthread_mutex_t mutex;
pthread_cond_t cond;
void* even(void *v)
{
    //cout<<"even thread"<<endl;
    while(count<maxx)
    {
        pthread_mutex_lock(&mutex);//lock before checking
        while((count%2)==0)
        {
            pthread_cond_wait(&cond,&mutex);//wait until count becomes odd
            //it releases the mutex and it waits till condition cond is signaled as complete and mutex is available.
        }
        cout<<"even "<<count++<<endl;
        pthread_mutex_unlock(&mutex);//release
        pthread_cond_signal(&cond);//signal to another thread
    }
    pthread_exit(0);//pthread_exit is called from the thread itself to terminate its execution (and return a result) early.
}
void* odd(void *o)
{
    while(count<maxx)
    {

        pthread_mutex_lock(&mutex);//lock before checking
        while((count%2)==1)
        {
            pthread_cond_wait(&cond,&mutex);//wait until count becomes odd
        }
        cout<<"odd "<<count++<<endl;
        pthread_mutex_unlock(&mutex);//release
        pthread_cond_signal(&cond);//signal to another thread
    }
    pthread_exit(0);
}
int main()
{
    pthread_t t1;
    pthread_t t2;

    pthread_mutex_init(&mutex, 0);
    pthread_cond_init(&cond, 0);

    pthread_create(&t1,NULL,&even,NULL);
    pthread_create(&t2,NULL,&odd,NULL);
    pthread_join(t1,0);
    pthread_join(t2,0);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    //pthread_join is called from another thread to wait for a thread to terminate and obtain its return value
    cout<<endl;
    return 0;
}
/*
odd 0
even1
odd 2
even3
odd 4
even5
odd 6
even7
odd 9
even10
*/

Simple logger class implementation code example in c++

//main.cpp
#include "Logger.h"
int main(int argc, char *argv[])
{
    string message1 = "logg message 1 ...";
    string message2 = "logg message 2 ...";
    int    nNum     = 10;
    CLogger::getLogger()->Log("\nmessage to be logged------------------>\n");
    CLogger::getLogger()->Log(message1);
   
    CLogger::getLogger()->Log("\nmessage to be loggedi again-------------------->\n");
    LOGGER->Log("\nMessage is:%s Number is:%d",message1.c_str(), nNum,"\n");//#define LOGGER CLogger::getLogger()

    CLogger::getLogger()->Log("\nmessage to be loggedi again------------------------>\n");
    CLogger *ptr1;
    ptr1=CLogger::getLogger();
    ptr1->Log("\nMessage Logged\n");           

}
//logger.h
#ifndef CUSTOM_CLogger_H
#define CUSTOM_CLogger_H
#include <fstream>
#include <iostream>
#include <cstdarg>
#include <string>
using namespace std;
#define LOGGER CLogger::getLogger()
/**
 *   Singleton Logger Class.
 */
class CLogger
{
public:
    /**
     *   Logs a message
     *   @param sMessage message to be logged.
     */
    void Log(const std::string& sMessage);
    /**
     *   Variable Length Logger function
     *   @param format string for the message to be logged.
     */
    void Log( const char * format, ... );
        /**
     *   << overloaded function to Logs a message
     *   @param sMessage message to be logged.
     */
    CLogger& operator<<(const string& sMessage );
    /**
     *   Funtion to create the instance of logger class.
     *   @return singleton object of Clogger class..
     */
    static CLogger* getLogger();
private:
    /**
     *    Default constructor for the Logger class.
     */
    CLogger();
    /**
     *   copy constructor for the Logger class.
     */
    CLogger( const CLogger&){};             // copy constructor is private
    /**
     *   assignment operator for the Logger class.
     */
    CLogger& operator=(const CLogger& ){ return *this;};  // assignment operator is private
    /**
     *   Log file name.
     **/
    static const std::string m_sFileName;
    /**
     *   Singleton logger class object pointer.
     **/
    static CLogger* m_pThis;
    /**
     *   Log file stream object.
     **/
    static ofstream m_Logfile;
};
#endif
//logger.cpp
#include "Logger.h"
//#include"Utilities.h"
const string CLogger::m_sFileName = "Log.txt";
CLogger* CLogger:: m_pThis = NULL;
ofstream CLogger::m_Logfile;
CLogger::CLogger()
{

}
CLogger* CLogger::getLogger(){
    if(m_pThis == NULL){
        m_pThis = new CLogger();
        m_Logfile.open(m_sFileName.c_str(), ios::out | ios::app );
    }
    return m_pThis;
}

void CLogger::Log( const char * format, ... )
{
    char sMessage[256];
    va_list args;
    va_start (args, format);
    vsprintf (sMessage,format, args);
//    m_Logfile <<"\n"<<Util::CurrentDateTime()<<":\t";
    m_Logfile << sMessage;
    va_end (args);
}

void CLogger::Log( const string& sMessage )
{
    //m_Logfile <<"\n"<<Util::CurrentDateTime()<<":\t";
    m_Logfile << sMessage;
}

CLogger& CLogger::operator<<(const string& sMessage )
{
    //m_Logfile <<"\n"<<Util::CurrentDateTime()<<":\t";
    m_Logfile << sMessage;
    return *this;
}
//Log.txt

message to be logged------------------>
logg message 1 ...
message to be loggedi again-------------------->

Message is:logg message 1 ... Number is:10
message to be loggedi again------------------------>

Message Logged
//Courtesy cppcodetips.wordpress.com

Initialization List examples code in C++ in Linux

/*1) For initialization of non-static const data members:
const data members must be initialized using Initializer List. In the following example, “t” is a const data member of Test class and is initialized using Initializer List.
*/
#include<iostream>
using namespace std;

class Test {
    const int t;
public:
    Test(int t):t(t){} //error: assignment of read-only member ‘Test::t’ if assignment is used
    //Test(int t){this->t=t;} //error: assignment of read-only member ‘Test::t’ if assignment is used
    int getT() { return t; }
};

int main() {
    Test t1(10);
    cout<<t1.getT()<<endl;;
    return 0;
}

/* OUTPUT:
   10
*/
/*2) For initialization of reference members:
Reference members must be initialized using Initializer List. In the following example, “t” is a reference member of Test class and is initialized using Initializer List.
// Initialization of reference data members*/
#include<iostream>
using namespace std;

class Test {
    int& t;
public:
    Test(int &t):t(t) {cout<<"constructor\n";}
    //Test(int &t) {this->t=t;}  //error: uninitialized reference member ‘Test::t’
    int getT() { return t; }
};

int main() {
    int x = 20;
    Test t1(x);
    cout<<t1.getT()<<endl;
    x = 30;
    cout<<t1.getT()<<endl;
int y=100;
    cout<<t1.getT()<<endl;

//    Test t(400);//error: no matching function for call to ‘Test::Test(int)’
    return 0;
}
/* OUTPUT:
    20
    30
    30
 */
//3.//Initialer list is used for initializing contained class object which does not have a default copy constructor.
#include <iostream>
using namespace std;

class A {
    int i;
public:
    A(int );
};

A::A(int arg) {
    i = arg;
    cout << "A's Constructor called: Value of i: " << i << endl;
}

// Class B contains object of A
class B {
    A a;
public:
    B(int );
};

B::B(int x):a(x) {  //Initializer list must be used
    cout << "B's Constructor called";
}

int main() {
    B obj(10);
    return 0;
}
/* OUTPUT:
    A's Constructor called: Value of i: 10
    B's Constructor called
*/
/*4) For initialization of base class members : Like point 3, parameterized constructor of base class can only be called using Initializer List.*/
#include <iostream>
using namespace std;

class A {
    int i;
public:
    A(int );
};

A::A(int arg) {
    i = arg;
    cout << "A's Constructor called: Value of i: " << i << endl;
}

// Class B is derived from A
class B: A {
public:
    B(int );
};

B::B(int x):A(x) { //Initializer list must be used
    cout << "B's Constructor called"<<endl;
}

int main() {
    B obj(10);
    return 0;
}
/*
A's Constructor called: Value of i: 10
B's Constructor called
*/
/*5) When constructor’s parameter name is same as data member
If constructor’s parameter name is same as data member name then the data member must be initialized either using this pointer or Initializer List. In the following example, both member name and parameter name for A() is “i”.
*/
#include <iostream>
using namespace std;

class A {
    int i;
public:
    A(int );
    int getI() const { return i; }
};

//A::A(int i):i(i) { }  // Either Initializer list or this pointer must be used
// The above constructor can also be written as
A::A(int i) {
    this->i = i;
    //i = i;//some garbage
}


int main() {
    A a(10);
    cout<<a.getI()<<endl;
    return 0;
}
/* OUTPUT:
    10
*/

Factory Design pattern code example in C++

Factory Design pattern is achieved in 2 ways:
1. By giving a abstract interface class or and giving object create method in concrete class derived from interface class
2. By giving object create method in Factory class
2.  Factory Design pattern: defines interface to create objects. Object creation not required directly by client instead it is created in provided interface. Advantage is that client does not require to know exact class name whose object it wants to create. Also object instantiation is delayed till factory's create() method call so its like virtual constructor as exact class name is not required during compile time.
#include<iostream>
using namespace std;
#include<string.h>
class Button
{
public:
    virtual void paintButton()=0;
};
class OsLinuxButton: public Button
{
public:
    void paintButton()
    {
    cout<<"OsLinuxButton::paintButton"<<endl;
    }   
};
class OsWindowButton: public Button
{
public:
    void paintButton()
    {
    cout<<"OsWindowButton::paintButton"<<endl;
    }   
};
class GuiFactory
{
public:
    virtual Button* createButton(char* but)//No abstract
    {
    if(strcmp(but,"window")==0)
    {
    return new OsWindowButton;
    }
    if(strcmp(but,"linux")==0)
    {
    return new OsLinuxButton;
    }
    }
};
class Factory: public GuiFactory
{
public:
    Button* createButton(char* but)
    {
    if(strcmp(but,"window")==0)
    {
    return new OsWindowButton;
    }
    if(strcmp(but,"linux")==0)
    {
    return new OsLinuxButton;
    }
    }
};

int main()
{
Button *button1;
GuiFactory * guifactory=new Factory;
button1 = guifactory->createButton("window");
button1->paintButton();

Button *button2;
GuiFactory * guifactory2=new Factory;
button2 = guifactory->createButton("linux");
button2->paintButton();
return 0;
}

Example 2:
//Abstract factory Design pattern: defines interface to create family of objects. Object creation not required directly by client instead it is created in provided interface. Advantage is that client does not require to know exact class name whose object it wants to create. Also objectinstantiation is delayed till factory's create() method call so its like virtual constructor as exact class name is not required during compile time.
#include<iostream>
using namespace std;
#include<string.h>
class Button
{
public:
    virtual void paintButton()=0;
};
class OsLinuxButton: public Button
{
public:
    void paintButton()
    {
    cout<<"OsLinuxButton::paintButton"<<endl;
    }  
};
class OsWindowButton: public Button
{
public:
    void paintButton()
    {
    cout<<"OsWindowButton::paintButton"<<endl;
    }  
};
/*
class GuiFactory
{
public:
    virtual Button* createButton(char* but)=0;
};
class Factory: public GuiFactory
{
public:
    Button* createButton(char* but)
    {
    if(strcmp(but,"window")==0)
    {
    return new OsWindowButton;
    }
    if(strcmp(but,"linux")==0)
    {
    return new OsLinuxButton;
    }
    }
};
*/
int main()
{
/*
Button *button1;
GuiFactory * guifactory=new Factory;
button1 = guifactory->createButton("window");
button1->paintButton();

Button *button2;
GuiFactory * guifactory2=new Factory;
button2 = guifactory->createButton("linux");
button2->paintButton();
*/
//Without factory Object is ctreated in client code itself.
//client does new so may effect the code. Separate interface is not defined to create object.
Button *button=new OsLinuxButton;
button->paintButton();

Button *buttonWindow=new OsWindowButton;
buttonWindow->paintButton();
return 0;
}

Abstract factory Design pattern code example in cpp

Abstract factory Design pattern: defines interface to create family of objects. Object creation not required directly by client instead it is created in provided interface. Advantage is that client does not require to know exact class name whose object it wants to create. Also object instantiation is delayed till factory's create() method call so its like virtual constructor as exact class name is not required during compile time.
#include<iostream>
using namespace std;
#include<string.h>
class Button
{
public:
    virtual void paintButton()=0;
};
class OsLinuxButton: public Button
{
public:
    void paintButton()
    {
    cout<<"OsLinuxButton::paintButton"<<endl;
    }   
};
class OsWindowButton: public Button
{
public:
    void paintButton()
    {
    cout<<"OsWindowButton::paintButton"<<endl;
    }   
};
class GuiFactory
{
public:
    virtual Button* createButton(char* but)=0;
};
class Factory: public GuiFactory
{
public:
    Button* createButton(char* but)
    {
    if(strcmp(but,"window")==0)
    {
    return new OsWindowButton;
    }
    if(strcmp(but,"linux")==0)
    {
    return new OsLinuxButton;
    }
    }
};

int main()
{
Button *button1;
GuiFactory * guifactory=new Factory;
button1 = guifactory->createButton("window");
button1->paintButton();

Button *button2;
GuiFactory * guifactory2=new Factory;
button2 = guifactory->createButton("linux");
button2->paintButton();
return 0;
}

Example2:

C++ reference FAQ interview questions

//1.References are nothing but constant pointer.
//2.So,references once initialized can not refer to other.
//2.1 Reference to reference not allowed.No error but. it will start pointing to the first variable
//3. reference arithmatic not allowed.No error in reference arithmatic but changes reflected in referant not in reference.
//4.Reference to array allowed.//int (&r)[5];
//5.Array of reference not allowed because we can not find the address of array. ultimately refer to first variable.
//6.Unlike pointers,refernce are automatically gets dereferenced.No need to use *(value at address).
//7.Unlike pointers, reference arithmatic like increment will increase the referant's value and not the address
//8.Reference are used to pass by reference to get the changes reflected in calling function.
//9.Pass by reference avoids copy of large value when structure like data are passed as arguments.
//10. Its unsafe to return local variable by value because variable goes out of scope once conrol returns out of the function defintion.
//Solution is us local static variable or dynamic memory allocation so that scope of the variable will through out the program.
#include<iostream>
using namespace std;
int gv;
int main()
{
//reference nothing but constant pointer means once initialized can not be reinitialized.
int s=10;
int *const h=&s;//s is const pointer so can not hold another address
//h=&m;//error: assignment of read-only variable ‘h’


int i=10,m=2;
int &j=i;// j is reference to a

//reference to refernce not allowed. No error but points to the first variable
int &k=j;//reference to reference no error but//point 2.1
k=20;
cout<<i<<endl;//20

//pointer arithmatic are not allowed. no error but changes gets reflected in first variable
k++;//point 7
cout<<i<<endl;//21

//referece can not be reinitialized but direct values can be given
int a=1;
k=1;
cout<<k<<endl;

//pass by reference to get the values reflected in calling function
int x=10,y=20;
swap(x,y);
cout<<x<<" " <<y<<endl;//20,10

//if return type is reference then function call can be made in left side
int &f();
f()=5;
cout<<"gv="<<gv<<endl;//5//instead of returned reference 100, f() is assigned to 5

//problem of local ovariable returning by value
int d;
int ff(d);
cout<<"d="<<d<<endl;//Garbage, because return value went out of scope in definition itself.
return 0;
}
void swap(int x, int y)
{
int t;
t=x;
x=y;
y=x;
}
//return by reference
int &f()
{
gv=100;
return gv;
}
//problem of returning local variable by value
int ff(int t)
{
int& lv=t;
lv=lv+44;
return lv;//returning local variable by value.
}//scope of lv over here
You may also like.