Thursday, March 29, 2012

Virtual constructors in C++!!

When you try to declare a constructor as virtual in C++ and compile, you will get compile time error saying that "error: constructors cannot be declared virtual". This is because in C++, constructors can't be declared as virtual. lets see why?

Virtual functions in C++ are implementation of run time polymorphism. And they will do function overriding.  Generally virtual keyword used in C++ when you need Dynamic behavior. It will work only when object exists.  Where as constructors are used to create the objects. Constructors will be called at the time of object creation.

So if you create the constructor as virtual, as per the virtual keyword definition, it should have existing object to use, but constructor is to creating the object, these two will never exists. So should not use the constructor as virtual.

You can use virtual destructors because, at the time of calling destructor, you have the objects. So you can use virtual keyword for the destructors.

Wednesday, March 28, 2012

function pointers in C?

function pointer is a pointer variable, just like a normal pointer. but function pointer points to the address of the function. In C like all normal variables, functions also will be stored in the memory. So every function will have valid address. function pointer will point to this address.

Sample code to display address of a function:

void dis()
{
    printf("Demo for printing function address \n");
}
main()
{
    printf("address of dis() function is %x\n",dis);
}


Output:
address of dis() function is 4004d8

How to declare a function pointer: declaring a function pointer looks little confusing. But if you understand the concept of the function pointer, it will be very easy. Lets take declaration of a normal pointer variable, we will do it by using *(asterisk) with variable name. Similarly for function pointer also , we need to use * with function pointer name with in the braces. If you not enclosed in braces, it is not a function pointer.

Syntax:
// declaring the function pointer which takes zero arguments and returns void
void (*funcPtr)(); 

//this is not a function pointer, because there are no braces. This function will take zero arguments and returns void pointer. 
void *funcPtr(); 

Assigning function pointer: Assigning a function address to a function pointer is like a normal assignment. But signature of the function should match to the function pointer. i.e no. arguments and return type should match the signature. while assinging the fucntion address to the function pointer ampersand(&) is optional.

//function for adding two int's
int int_add(int x, int y)
{
    return (x+y);
}

//function pointer declaration
int (*fncPtr)(int, int);

//assigning
fncPtr = &int_add;

// this is also valid
fncPtr = int_add;


Calling a function using function pointer: Calling a function using function pointer is like a normal function call only. you can use function pointer or function name, both works in a same way.

// calling normal function
int sum = int_add(2,3);

// calling function using function pointer
int sum = fncPtr(2,3)

Complete working Example:
int int_add(int x, int y)
{
    return (x+y);
}

//function pointer declaration
int (*fncPtr)(int, int);

main()
{
    fncPtr = &int_add; //assigning the fucntion address to pointer
    int sum = fncPtr(2,3); // calling function using fuction pointer
    printf("sum is %d\n",sum);
    sum = int_add(5,3); // callint normal function
    printf("sum is %d\n",sum);
}


Output:
sum is 5

sum is 8

Uses of funtion pointers: This will be usefull for call back functions, where the calling definition changes dynamically. This is similar to runtime binding or late binding in C++ which can be implemented using virtual functions.  For example take the implementation of a qsort() library function in Unix. from the man pages prototype is given below.

void qsort(void *base, size_t nmemb, size_t size,
                  int(*compar)(const void *, const void *));


In the above qsort prototype, third argument is a function pointer to 'compar' function, which takes two void pointers as arguments and returns integer value. Compar function works for any data type, and it return zero if both are equl , return 1 if first one is greater than second and returns -1 if second argument is greater.



Tuesday, March 27, 2012

Virtual destructors in C++

C++ gives default destructor, if you not define the destructor. But this wont be help full if you use dynamic memory allocation. You need to write the destructor function manually to deallocate the memory. This works fine if there is no derived class. If there is any derived class with memory allocation, you should use virtual destructors. see the sample code below.

#include<iostream>
using namespace std;

class base
{
    public:
    base()    //constructor
    {
        cout<<"this is base CTOR\n";
    }

    ~base()    //not a virtual destructor
    {
        cout<<"this is base DTOR\n";
    }
};
class derived:public base
{
    char *str;
    public:
    derived()
    {
        cout<<"this is derived CTOR\n";
        str = new char[20]; // allocating space
    }
    ~derived()
    {
        cout<<"this is derived DTOR\n";
        delete[] str; // deleting
    }
};
main()
{
    derived *d = new derived(); // creating derived object
    base *b = d; // assigning derived object to base object
    delete b; // deleting base object

}

Output:
this is base CTOR
this is derived CTOR
this is base DTOR

In the above sample code, there is derived class with char pointer member data. Memory is allocated in derived constructor and deallocated in derived destructor. In main() function , derived object is created using new,  this is assigned to base object. And base object is deallocated using delete.  In the output you got, base constructor, derived constructor, and base destructor. And there is no derived destructor. Actually, we allocated memory in derived constructor.  so there is a memory leak, because we are not freed the allocated memory.

To avoid such problems, we need to use virtual destructors. Actually compiler looks for the base destructor and checks for the virtual keyword for the destructor, if it finds virtual keyword, it further goes to derived destructor and goes on till the refered derived class. from there it calls destructor one by one from derived destructor to till it reaches base destructor.  If there is no virtual keyword in the base destructor, it stops in base destructor itself. See the sample code with virtual destructor.


Code with virtual destructor:

#include<iostream>
using namespace std;

class base
{
    public:
    base()    // base constructor
    {
        cout<<"this is base CTOR\n";
    }
    virtual ~base()    // virtual destructor
    {
        cout<<"this is base DTOR\n";
    }
};
class derived:public base
{
    char *str;
    public:
    derived()
    {
        cout<<"this is derived CTOR\n";
        str = new char[20]; // allocating space
    }
    ~derived()
    {
        cout<<"this is derived DTOR\n";
        delete[] str; // deleting
    }
};
main()
{
    derived *d = new derived(); // creating derived object
    base *b = d; // assigning derived object to base object
    delete b; // deleting base object

}

Output:
this is base CTOR
this is derived CTOR
this is derived DTOR
this is base DTOR


In this example, we used virtual destructor, when it calls deleting base pointer, it looks for the base destructor, then it looks for the virtual  keyword for the destructor, it will get the keyword, so it looks for the derived destructor, it finds the destructor, and there is no derived classes, so it calls the derived destructor, then it calls the base destructor as shown above. In red color output , is the derived destructor.

Monday, March 26, 2012

Virtual functions in C++!!!

A Virtual function  is a special type of function, which resolve to most-derived function with the same prototype. To make a function virtual, just use virtual keyword before the function. This is also called function overriding or runtime polymorphism.

Lets see the use of virtual functions. Assume that there is a base class with one member function. And one derived class with another member function with same name as in base class. If you try to call that member function as shown in the below sample code.

#include <iostream>
using namespace std;
struct base
{

    public:
        void display()
        {
            cout<<"this is base class\n";
        }

};

class derived: public base
{
    public:
        void display()   // same function there in base class also
        {
            cout<<"this is derived class\n";
        }
};

int main()
{
    derived d;
    base &b = d; // refering base object to derived object
    b.display();
}


Output:
this is base class


From the above sample code, the expected result should be from derived function as base object is referring to the derived object. But we got the base function. Even though , base object is referring to derived object, it wont resolves to derived class. To avoid this we need to use the virtual  keyword. See the same sample code with virtual keyword.

Example With Virtual keyword:

#include <iostream>
using namespace std;
struct base
{

    public:
        virtual void display()   // using virtual keyword
        {
            cout<<"this is base class\n";
        }

};

class derived: public base
{
    public:
        void display()  //same function is there in base class
        {
            cout<<"this is derived class\n";
        }
};

int main()
{
    derived d;
    base &b = d; // refering base object to derived object
    b.display();

}

Output:
this is derived class


Now we got the expected output, this is because of the virtual  keyword. If you use virtual keyword, it will check for resolving function for the derived classes, starting from the base class to referred derived class.

Another Example with more derived classes:
#include <iostream>
using namespace std;
struct base
{

    public:
        virtual void display()
        {
            cout<<"this is base class\n";
        }

};

class derived: public base
{
    public:
        void display()
        {
            cout<<"this is derived class\n";
        }
};

class derived1: public derived
{
    public:
        void display()
        {
            cout<<"this is derived1 class\n";
        }
};
class derived2: public derived1
{
    public:
        void display()
        {
            cout<<"this is derived2 class\n";
        }
};
int main()
{
    base b1;
    derived1 d;
    base &b = d; // base object refering to direved1 object
    b.display();

}

Output:
this is derived1 class


In the above sample code, base object is refering to derived1 object, so resolving process starts from the base class, it checks for the virtual keyword, if it finds the keyword, it goes to the derived class, this process goes on til it reaches the refered object, here it is derived1.

Use of Virtual keyword: To implement virtula functions, we need to use the virtual keyword in base class. And its optional to use in derived class. But its better to use in derived class also, so that you are informing that that function is a virtual function. Generally most base class function need to be used virtual.

Friday, March 23, 2012

Reference variable in C++!!

C++ is a call by reference language. So it supports reference variables. A reference variable is a alias to other variable. The reference variable behaves same like a original variable it is referencing. Reference variable is like a const pointer that is implicitly dereferenced. These variables are declared using ampersand (&). Referance variable should not be NULL. It should refer to some value.

Simple exampe:

#include&lt;iostream>
using namespace std;
main()
{
    int iVar = 10;
    int& rVar = iVar; // declaring the reference variable
    int& rVar1;  // illegal , reference variable should refer to some variable
    rVar=20;
    cout<<"ivar is "<<iVar<<endl;
    cout<<"rvar is "<<rVar<<endl;
}

Output:
ivar is 20
rvar is 20

Reference variable is same as normal variable, if you modify the normal , reference variable effects and vice-varsa.

Reference variable can't be redirected: Reference variable cant't be redirected to other variable. i.e. once assigned to a variable cant ba assigned to other variable. See the sample code below.

    int& rVar = iVar; // declaring the reference variable
    int iVar2 =30;
    rVar  = iVar2;  // it only assigns the value of iVar2 to rVAr


In the above code snippet, rVAr is a reference variable and is referencing to iVar. In the third statement, iVar2 is assigning to rVar. Here it will assign only value. And it will not change the reference variable. It will reference to iVar only.

Constant reference: C++ allows to use constant references. A constant reference will not allow you to change the value it referenced. 
    int iVar = 10;
    int const &cVar = iVar; // declaring constant reference variable
    cVar = 40; // illegal, cant change the constant referenc
    iVar = 40; // legal, can change normal variable



Uses of reference pointer:

1. Const reference used as function parameters:  As constant reference variables are read only access. It wont allow to modify the value. so passing value as function arguments, it will be vary useful. Constatn reference used in copy constructors for passing object as a argument.


2. Easy access to the nested data: If there are nested data like structure in a structure in as structure. to access the data , we need to use specify each structure variable with dot operator. Using refernce varaible , we can reduce this. See the sample code below.

#include<iostream>
using namespace std;

struct str
{
    int x;
};
struct str1
{
    struct str s;
    int x;
};

struct str2
{
    struct str1 s;
    int x;
};


main()
{

    struct str2 ins;
    ins.x=10;
    ins.s.s.x = 20;
    int &strRef = ins.s.s.x;
    strRef = 40;
    cout<<"strf ref is "<<strRef<<endl;
    cout<<"struct x is "<<ins.s.s.x<<endl;
}

Output:
strf ref is 40
struct x is 40

In the above code, structure str2 member is structrure str1, and its memeber is structure str. To access that , you need to specify all the structure variable with dot operator, instead of this, you can use reference variable to access it as shown in the code.




Thursday, March 22, 2012

Exception handling in C++!!

              C++ supports exception handling feature. It will be implemented using try, throw and catch keywords.This is used to exit the application in a proper way after getting the errors like divided by zero or finding the square root of a negative no. or fatal errors. This will throw an error message depending on the error codes.
 
           In C++, exception handling works in such a way that, it looks for the possible errors in try block and if error or exception occurs, it will throw the error. And thrown error in try block will be handled in catch block. Throwing an exception is just jumping the control flow to the catch block when error occurs. After throw statements never execute when exception occurs. Below is simple example.

#include<iostream>
using namespace std;

int main()
{
    try
    {
        throw 3;
    }
    catch(int i)
    {
        cout<<"caught value "<<i<<endl;
    }

    return 0;
}


OutPut:
caught value 3


The above sample code excute the try block, there it throw the numeric value three, so it looks for the corresponding catch block for int , so it displays the message.
Another example by throwing string:

Sampel code for throwing string:
#include<iostream>
#include<math.h>
using namespace std;

main()
{
    try
    {
        int num;
        cout<<"enter the number for square root"<<endl;
        cin>>num;
        if(num<0)
        {
            throw "can't find square root for negative numbers";
        }
        cout<<"sqrt is "<<sqrt(num)<<endl;
    }
    catch( char const *str)
    {
        cout<<str<<endl;
    }
}

Output:
enter the number for square root
4
sqrt is 2

enter the number for square root
-3
can't find square root for negative numbers


Above sample code in try block excutes and check for the condition and throws a constant string when negative no. occurs. After throwing, it looks for the corresponding catch block and displays the messages.

Till now we have seen the example of using throw with in the try block. But most of the cases are different, where throwing an exception is not in try block. So what exactly compiler does is that, it will check for immidiate catch block , if not , it will send to its caller function, there it checks for the catch block and goes on till it reaches corresponding catch block or till it reaches main function. This process is called stack unwinding.

Example for stack unwinding:

#include<iostream>
using namespace std;

void fun2()
{
    throw "throwing exception in func2\n";
}

void fun1()
{
    cout<<"in fun1()\n";
    try
    {
        fun2();
    }
    catch(char *)
    {
        cout<<"exception caught in fun1\n"<<endl;
    }
}
void display()
{
    cout<<"in display()\n";
    fun1();
}
main()
{
    try
    {
        cout<<"in main function\n";
        display();
    }
    catch(char const*str )
    {
        cout<<"exception caught in main \" "<<str<<"\""<<endl;

    }
}

OutPut:
in main function
in display()
in fun1()
exception caught in main " throwing exception in func2"

In the above sample code, main function calls display() and it calls fun1() and it calls fun2(), fun2() throws exception with constant string, but fun2() don't have catch block, so it returns to its caller fun1(), fun1() is having catch() block, but it is not a constant string , so it returns its caller fun(), fun() don't have catch block, it returns to its caller main(). main has its corresponding catch block, so exception caught in main function.


What happens if no matching catch block: Generally compiler looks for the matching catch block. If there is no catch block, application terminates with a error message depending on the compiler. In GNU C++ compiler the error message is "terminate called after throwing an instance of" for no matching catch for exceptions. To avoid such cases C++ provides a default catch block with (...) three consecutive dots in a catch. If you have no idea what to throw, just use default throwing three dots (...) similar to default catch.

Sample code for no matcing catch block:

#include<iostream>
using namespace std;

int main()
{
    try
    {
        throw 3;
    }
    catch(char )
    {
        cout<<"caught exception "<<endl;
    }

    return 0;
}

OutPut:
terminate called after throwing an instance of 'int'
Aborted

In the above code, try block throwing int value, but there is no catch block to handle int value, so it will abort the process with the error message as shown in the output.
Sample code for default catch block:
#include<iostream>
using namespace std;

int main()
{
    try
    {
        throw 3;
    }
    catch(...)
    {
        cout<<"caught exception "<<endl;
    }

    return 0;
}
OutPut:
caught exception

In above samle code, try block throws int exception, but there is no int catch block,there is a default catch block to handle any exception.

Wednesday, March 21, 2012

Code for Product or multiplication of polynamial equation !!!

The source code for multiplication of the polynomial equation is given below with explanation. Inputs for this program are polynomial equations and their order.

Calculating product of the polynomial: This function takes two polynomial equations and their orders as a input stores the result in another array.

/****************************************************
Name: poly_mult
Input: equation one , order of equation one, equation two, order of eq two, result.
return: void

description: it will take the two polynomial equations and stores the result in prod_poly.

****************************************************/
void poly_mult(float equ1[], unsigned equ1_expo, float *equ2, unsigned equ2_expo, float *prod_poly)
{
 unsigned i, j;

 for(i=0;i<equ1_expo;i++)
 {
  for(j=0;j<equ2_expo;j++)
  {
   prod_poly[i+j]=(equ1[i] * equ2[j])+prod_poly[i+j];
   //   printf("i+j value is %f \n",prod_poly[i+j]);
  }
 }
}

Displaying the polynomial Equation: This function just take the input and displays as a polynomial equation form.

/****************************************************
Name: print_trxfunc
Input: equation, equation order
return: void

description: it just prints the given equation
****************************************************/
void print_trxfunc(float *equ, unsigned expo)
{
 unsigned i;

 printf("\t\t");
 for(i=expo;i>0;i--)
 {
  if(equ[i]!=0 && equ[i]>0)
  printf("+ %fx%u ", equ[i], i);
  if(equ[i]!=0 && equ[i]<0)
  printf(" %fx%u ", equ[i], i);
 }

 if(equ[0]!=0 && equ[0]>0)
  printf("+ %f", equ[0]);
 if(equ[0]!=0 && equ[0]<0)
  printf(" %f", equ[0]);
 printf("\n");
}

Validating the characters: This function checks for the valid characters  in a equation. The valid characters are  +, -, ., x, space, digits other wise it returns zero as invalid character.

/****************************************************
Name:check_char
Input: takes the char as a input
return: returns int

description: it will take the char as input and check for the 
space, digit, 'x', and +,-, . symbols n returns the corresponding code otherwise zero it returns
****************************************************/
int check_char(char a)
{
 if(isspace(a)) return 1;
 else if(isdigit(a)) return 2;
 else if(isalpha(a) && (a='x')) return 3;
 else if(a=='+' || a=='-' ) return 4;
 else if(a=='.') return 5;
 return 0;
}

Separating exponential: This function will separate the exponential part from the given input equation and stores in a int varaibel. e.g 2x2+3x+4  in this equation , this functins separates 2 from 2x2 and 1 from 3x and zero from 4.

/****************************************************
Name: find_expo
Input: equation, expo, index
return: returns index

description: this function will separate the exponential of the each x and stores in expo.
****************************************************/
int find_expo(char *eq, int *expo,int *i)
{
 char str_num[1024]={0};
 int index =  0;
 int dot_count = 0; //for float no.s only one dot should be there, more than means invalid equation
    int code;
 if(isalpha(eq[*i])) (*i)++; // this function works only if first char is alpha
 else
 {
  printf("invalid equation \n");
  exit(1);
 }
    // this for loop is copying numeric values to the arry str_num, which will be later converted to numeric using sscanf
    for(;!isalpha(eq[*i]);(*i)++,index++)
    {
        code = check_char(eq[*i]);
        if((code == 2)) // if digit , copy to array
            str_num[index]=eq[*i];
        else if (code == 4)
        {
   //printf("breaking the loop\n");
   break;
        }

    }
    str_num[index]='\0'; // appending the termination char to the array
    int temp;
 if(!index)
 {
  printf("invalid equation\n");
  exit(1);
 }
    sscanf(str_num,"%d",&temp);
    *expo = temp;
    return index;
}
Storing in array: This function will convert the equation and stores in memory in the form of array such that exponential is index of the array and coefficient is the value of that index. e.g  for 2x2+3x+4 this equation, arry[2] is 2 arry[1] is 3 and arry[0] is zero

/****************************************************
Name: store_coeff_arry
Input: equation, arry
return: void

description: this function will separate the coeff n expo from input equation and
stores them in an array. Internally it will call different functuinc to find coeff n expo
****************************************************/
void store_coeff_arry(char *eq, float *arry)
{
 int eq_len = strlen(eq);
 int i=0;
 int sign = 0; 
 int init_sign = 1; 
 int sts;
 int pos=0;
 float coeff;
 int expo=0;
 for(;i<eq_len;i++)
 {
  if(isspace(eq[i])) 
      continue; 
  sts=check_char(eq[i]);
  if( (sts == 4))  //is a sign
  {
   sign=(eq[i]=='+') ? 1 : -1;
   pos = find_coeff(eq,&coeff,&i);
   i--; 
   pos=0;
  }
  else if(sts == 3 )       // is a alphabet
  {
   pos=find_expo(eq,&expo,&i);
   i--;
   pos=0;
   arry[expo] = coeff*sign;
   sign=0;
   coeff=0;
   expo=0;
  }
 }
}

Separating the coefficients: This function separates the coefficients from the given equation and stores in a variable. e.g 2x2+3x+4 , this function separates 2, 3 and 4 as a coefficients

/****************************************************
Name: find_coeff
Input: equation , coeff, index
return: index

description: this function separates the coef from given input and stores in coeff and retunrs the index.
****************************************************/

int find_coeff(char *eq, float *coeff,int *i)
{
 char str_num[1024]={0};
    int index =  0;
    int dot_count = 0; //for float no.s only one dot shouls be there, more than means invalid equation
    int code;
 if((eq[*i]=='+')|| (eq[*i]=='-')) 
  (*i)++; // this function works only if first char is sign
 else
 {
  printf("invalid euation \n");
  exit(1);
 }
    // this for loop is copying numeric values to the arry str_num, which will be later converted to numeric using sscanf
    for(;!isalpha(eq[*i]);(*i)++,index++)
    {
  code = check_char(eq[*i]);
        if((code == 2)) // if digit , copy to array
            str_num[index]=eq[*i];
        else if((code == 5)&& (!dot_count)) //if dot add to array n increment the dot count
        {
            str_num[index]=eq[*i];
            dot_count++;
        }
        else if(code == 4)
        {
         puts("In-correct equation format entered");
            exit(1);
        }

    }
 str_num[index]='\0'; // appending the termination char to the array
 float temp;
 if(!index)
 {
  printf("invalid equation\n");
  exit(1);
 }
 sscanf(str_num,"%f",&temp);
 *coeff = temp;
 return index;
}

Main function: This function asks for the order and equations , then calls store_coeff_arry() and stores the coeff and expo in an array and then it calls the prod_mult() to calculate the product and calls  print_trxfunc() to display the result in a equation format.

 
main()
{

 char eq[1024];
 float  *prod;
 float *poly1, *poly2;
 unsigned poly1_ord, poly2_ord;

 printf(" \nPoints to remember:\n");
 printf("1. Every coefficient should be represented numerically, i.e. x should be written as 1x1\n");
 printf("2. Every exponent should be represented numerically, i.e. 1 should be written as 1x0\n");
 printf("3. Example equation is: -10x7+23x9+ 137x3 -1x1 +3x0\n");
 printf("4. No space should be provided between coefficient and variable & coefficient and exponent.\n\n");


 printf("What will be the order of the polynomial one:\n");
 scanf("%u", &poly1_ord);
 printf("\n Enter polynomial equation : e.g +2x1+3x0 for 2x+3 \n ");
 scanf("%s", &eq);
 if(eq[0]!='+' && eq[0]!='-')
 {
  printf("invalid equation, please enter with sign \n");
  exit(0);
 }

 if((poly1=(float*)calloc(poly1_ord, sizeof(float)))==NULL)
 { 
  printf("\n\nNot enough memory space\n\n"); 
  exit(1); 
 }
 
 //storing the coeff in poly1
 store_coeff_arry(eq,poly1);

 printf("What will be the order of polynomial two:");
 scanf("%u",&poly2_ord);
 printf("\n Enter polynomial equation : e.g +2x1+3x0 for 2x+3 \n ");
 scanf("%s",&eq);
 if(eq[0]!='+' && eq[0]!='-')
 {
  printf("invalid equation, please enter with sign \n");
  exit(0);
 }

 if((poly2=(float*)calloc(poly2_ord, sizeof(float)))==NULL)
 { 
  printf("\n\nNot enough memory space\n\n"); 
  exit(1); 
 }

 //storing the coeff in poly2
 store_coeff_arry(eq, poly2);


 if((prod=(float*)calloc(poly1_ord+poly2_ord, sizeof(float)))==NULL)
 { 
  printf("\n\nNot enough memory space\n\n"); exit(1); 
 }
 
 //calculating the product n storing in prod
 poly_mult(poly1, poly1_ord, poly2, poly2_ord, prod);
 // printing the result 
 print_trxfunc(prod, poly1_ord+poly2_ord);

 free(prod);
 free(poly2);
 free(poly1);

}


Input format:

2x+3 should be given as +2x1+3x0
-3x2+4x+5 should be given as -3x2+4x1+5x0
Other wise results are undefined.

Sample Output: (2x+3)(2x+3)

+ 4.000000x2 + 12.000000x1 + 9.000000

P.S: Actually one of my cousin asked me the code for product of a polynomial equation. I used google for getting the code, but I could not get. So I thought of sharing this code. Just copy this code and try to compile in *nix system. you may get some compile time errors in windows(not sure).



Monday, March 19, 2012

What is STL in C++?

The Standard Template Library or simply STL is a container classes, algorithms and iterators of the C++ library. A container is object which contains the collection of the objects. These are implemented as a template classes. Before going into STL, better get the knowledge of Template classes in C++. The STL's are classified into following groups.

Container Classes:

1. Sequence Containers:
  • Vector: This is like dynamic array of variables, structs or objects. We can insert the data at the end. we can access the data using indexing.  see the example below.
  • De queue: Similar to array, and we can insert the data at the beginning and end. In this also we can access the data using indexing.
  • List: Similar to linked list. We can add/delete the data from anywhere.
2. Container Adaptors:
  • Stack: Same as Stack data structure. It uses LIFO concept.
  • Queue: Same as queue data structure. It uses FIFO concept.
  • Priority queue: Is a special adopter container, which contains the elements such a way that first element of the container is always greater.
3. Associative Adaptors:
  • Set : is a collection of ordered data in a balanced binary tree structure. And duplicate values are not allowed in SET
  • Multi Set: Same as SET, except duplicate values are allowed.
  • Map: is a collection of associated key-value pair in a balanced binary tree structure. And duplicate keys are not allowed.
  • Multi Map: Same as Map except, duplicate keys are allowed in multi-maps.

  Operations/Utilities on STL:

  •  Iterator:  This is used identify the elements in STL using position. This is also used to access the elements in the STL.
  • Algorithm: This is used to apply the function like find, sort, count, search on STL.
  • Auto_ptr: This is used for avoiding memory leaks. Using this , we can allocate the memory and no need of freeing the memory. auto_ptr will delete the allocated memory automatically after its use.

Vector Example:

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

// need to include corresponding STL header file. e.g vector file for vector STL
main()
{
    vector<int> v; // declaring the vector STL. similar to template
    for (int i =0;i<5;i++)
        v.push_back(10*i); // adding the element at the end

    vector<int>::iterator ii; // declaring the iterator
    for(ii=v.begin();ii<v.end();ii++)
        cout<<*ii<<" "; // accessing the value using iterator
}

Output:
0 10 20 30 40

Stack Example:

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

main()
{

    stack<int> st; // declaring stack STL
    for (int j=0;j<5;j++)
        st.push(j*10); // pushing the element into the stack
    while(!st.empty())   // checking for empty stack
    {
        cout<<" "<<st.top();   // getting the top of the stack element
        st.pop();    // deleting the element from the stack
    }
}
Output:
40 30 20 10 0


Friday, March 16, 2012

Templates in C++ !!

                Assume that there is a scenario where you need to find the max of two integers, double and char's. So you will write three different max functions for each. Here the code for all functions are same, the only difference is datatype. To avoid such a duplicate code , C++ supports a feature called Templates. Using templates, we can write a generic function which works for all data types. There are two types of templates namely function templates and class templates.
                The syntax is given below. It starts with template keyword followed by enclosing either class or typename keyword and generic type name in <, > and followed by function defintion. Both syntax's works similarly. There is no difference.

Syntax:
template <class generic_type [class generic_type] [class generic_type]>
function_definition

Function templates: A function template is like a normal function only, except the arguement type. A single function defintion works for different data types. A function will not store in memory. Actual function definition will be generated at the time of compilation basing on the data type.

 
Example:

using namespace std;

template <typename T>
T add(T a,T b)
{
    return (a+b);
}

main()
{
cout<<"2+3 is "<<(add(2,3))<<"\n";
cout<<"2.3+2.3 is "<<(add(2.3,2.3))<<"\n";
//cout<<"2+2.3 is "<<(add(2,2.3))<<"\n"; Illegal , arguments for the add function should be same type.
}

OutPut:
2+3 is 5
2.3+2.3 is 4.6

Class Template: Is a class in which member data are generic data types.See the below sample code .

using namespace std;

template <typename T>
class tmp{
    public:
        T a,b;
        tmp(T x, T y):a(x),b(y)
        {
            cout<<"a n b are "<<a<<" "<<b<<endl;
        }
};

int main()
{
tmp<int> o(2,3);
tmp<double> a1(2.3,3.4);
}

OutPut:
a n b are 2 3
a n b are 2.3 3.4

Thursday, March 15, 2012

GREP command in UNIX!!

The grep  is a very powerfull search command in Unix. It is used to search the string or pattern or regular exression in a file line by line and displays the line which contains the given pattern. grep stands for global regular expression parser or print. The grep family includes grep, egrep, fgrep.

Syntax:

grep [options] pattern filename

grep:   is a orginal command, its basic use to select the line and search for the string
egrep: is Extended grep and it uses extended regular expression (supporting logical OR in pattern) to select the lines to process. 
fgrep: is a Fast grep and it will not use the regular expressions, but it uses string literals to process.

Example for grep:

$grep ^[aeiou] test.txt
in a file line by
or print. The grep family
includes grep, egrep, fgrep
a son of srking.
a son of srqueen .

The above grep command searches for the patterns starting with vowel small letters in the starting of the line in the file test.txt and displays them
 
Example for egrep:
 
$egrep 'jr|sr|super ' test.txt
jrking is
a son of srking.
srking is a son of supersrking.
supersking grand sun is jrking.

$grep 'jr|sr|super ' test.txt
$


The above egrep searches for the strings jr or sr or super in test.txt file. single quotes are mandatory. grep displays nothing as it doesnot support logical OR.
 

Example for fgrep:

$fgrep king test.txt
jrking is
a son of srking.
srking is a son of supersrking.
supersking grand sun is jrking.

$fgrep ^[aeiou] test.txt
$

From the above examples, in the first fgrep  is looking for the string literal 'king' in test.txt and displays the lines which contains the 'king' literal. Where as in second command fgrep is looking for the regular expression ^[aeiou] and it displays nothing as fgrep doesn't support regular expressions. If you use grep  instead of fgrep , you will get the result as shown in example for grep above.

Some of usefull grep options:

-i : ignore the case
-r: search for the pattern recursively (usefull for searching in the directory/sub-directory)
-n: displays the lines with line no.s
-c: displays the count of the found patterns
-l: displays the file name which contains the given pattern (this is usefull while searching in sub-directories)

Wednesday, March 14, 2012

Find command in UNIX !!

The find comand is used to locate the files in unix or Linux systems. You can search for the files by name, owner, group, type, permission, date etc. syntax for the comman is given below.

          find whereToLook criteria WhatToDo

All feilds for the find command are optional, and all the feilds having the default values. i.e whereToLook defaults to . (current working directory), criteria defaults to none (showing all files in the pwd), WhatToDo defaults to -print, which means printing the find results on the standard output.

Example:

Unix78:~/> find 
Unix78:~/> find .
Unix78:~/> find . -print
Unix78:~/> find -print
All the above four commands will produce the same result. because of the default values.
OutPut:
.
./nosemicolon.c
./const.cpp
./leakc
./a.out
./struct.cpp

To find the exact file name:

              find / -name test.c

This will look for the file name test.c in the system (/ is for root) and displays the path. Here / is for whole system (you can specify required path) -name test.c is for Criteria saying that look for file name and WhatToDo feild is defaults to print. If there is no specified file in the system or specified path, find displays nothing.

Find command is need to run as a root. If you dont run as root, find will display error message for each directory on which you dont have read permission. To avoid these error message, we can redirect the message to null device as shown below.


     find / -name test.c 2>/dev/null


Some of the find criteria:

-name filename : search for the exact name
-iname filename : ignore the case . eg. test, Test, teSt all are same
-group gname: search based on group name (numeric grp name is allowed)
-gid n: files numeric grp id is n;
-P : never follow symbolic links. this is the default behaviour
-L : follow symbolic links 

Tuesday, March 13, 2012

Find the output of the following code snippets.


Snippet 1:

int get()
{
    int a[4]={10,20,30,40};
    int *p = &a[2];
    return (p[-1]);
}

main()
{
    int x=get();
    printf("x value is %d\n",x);
}

OutPut:
x value is 20

Explaination: Internal memory is like shown in the picture. P is pointed to the a[2]. So starting value for P is 30.As P is a pointer , we can move back and forth using index or by incrementing the pointer. P[-1] is 20 and p[-2 ] is 10. And P[-3 ] is not defined as the memry is not specified.  And we are returning a value and not a address. So there is no problem of returning the values.
Snippet 2:

class C{
public:
    C()
    {
        cout<<"this is constructor"<<endl;
    }
    ~C()
    {
        cout<<"this is destructor"<<endl;
    }
};
int main()
{
    C c;
    exit(0);
}


OutPut:
this is constructor

Explaination: Genarally, instantiating Class will create Constructor and while exiting it will call destructor. So expected output should be displaying constructor and destructor messages. But Because of the exit() function call, destructor will not call. exit function  calls before the destructor call. If you use anywhere in the application , need to call the destructor manually.

Snippet 3:

class base{
public:
    void display()
    {
        cout<<"base dispaly function"<<endl;
        func();
    }
    virtual void func()  
    {
        cout<<"base func function"<<endl;
    }
};
class derived: public base{
public:
    void func()
    {
        cout<<"derived func function"<<endl;
    }
};
main()
{
    derived d;
    d.display();
}


OutPut:
base dispaly function
derived func function

Explaination: There is a class base with two member functions display() and func() in which func() is a virtual. display() method calls func() in the definition. There is a derived class from the base , in which only func() definition is there in the derived class. If you try to call the display() function from the main as in the code snippet , we will get the above output. This is because of function overriding. Also called late or runtime binding. If you not use virtual  keyword, you will get only base method definitions.

Snippet 4:

struct s1
{
    int x,y;
};
struct s2
{
    int m,n,o;
};
main()
{
    struct s1 S1;
    S1.x=10;
    S1.y=20;
    struct s2 *S2;
    S2=&S1;
    printf("S2->m is %d\n",S2->m);
    printf("S2->n is %d\n",S2->n);
}

OutPut:
S2->m is 10
S2->n is 20

Explaination: Generally you will get the warning message while compilation. If you ignore warning message(as a developer, should not ignore the warnings :-)), we will get the above output. As it is handling with memory. Address of  S1 is assigned to S2. Now we can access using S2. If the memory allignment is fine(i.e data types are similar), it works fine(in our example). Other wise behaviour is undefined.

Monday, March 12, 2012

GDB: what is back trace ?

  Back trace or bt  is a summary of how the application or program came to the current position. It displays one line per frame starting from the current frame as zero and followed by its caller as frame one and so on up the stack till the main function as a last frame or nth frame.

Looking into Stack:
   As most of us know, whenever a function call occures, the information about the call is stored  in a memory region called call stack. For each function one stack frame or frame is created with function arguements, local variables, return address etc in call stack.
        In GDB, using back trace or bt command , we can get the call stack info or summary of the back traces. we can move from one frame to other using up and down gdb commands. we can get the details of the local varaibles in a frame with info locals command. See the sample code below with gdb out put.

(gdb) bt
#0  func3 () at stackFrame.c:5
#1  0x00000000004004e0 in func2 () at stackFrame.c:12
#2  0x000000000040050a in func1 () at stackFrame.c:18
#3  0x0000000000400534 in func () at stackFrame.c:24
#4  0x000000000040055e in display () at stackFrame.c:30
#5  0x000000000040056e in main () at stackFrame.c:34
(gdb) info locals
e = 0
(gdb) up
#1  0x00000000004004e0 in func2 () at stackFrame.c:12
12              func3();
(gdb) info locals
d = 10
(gdb) up
#2  0x000000000040050a in func1 () at stackFrame.c:18
18              func2();
(gdb) up
#3  0x0000000000400534 in func () at stackFrame.c:24
24              func1();
(gdb) frame 1
#1  0x00000000004004e0 in func2 () at stackFrame.c:12
12              func3();
(gdb) bt
#0  func3 () at stackFrame.c:5
#1  0x00000000004004e0 in func2 () at stackFrame.c:12
#2  0x000000000040050a in func1 () at stackFrame.c:18
#3  0x0000000000400534 in func () at stackFrame.c:24
#4  0x000000000040055e in display () at stackFrame.c:30
#5  0x000000000040056e in main () at stackFrame.c:34
(gdb) up
#2  0x000000000040050a in func1 () at stackFrame.c:18
18              func2();
(gdb)


        From the above GDB sesion, where all the gdb commands shown in blue color, bt gives the back trace of the prorgam in which program stopped in func3(). so frame zero is func3() which is called by func2() and followed by func1(), func(),display() and main() as the last stack frame.  Using frame gdb command, we can directly go to the desired frame by specifying frame number from the back trace.

Friday, March 9, 2012

What is Threaded binary tree?

The Binary tree traversals mostly involves stack manipulations which will take lot of memory. If the stack memory is low, Binary trees could be problems. Here comes the Threaded binary trees. These cane be useful where stack memory is limited or where stack of the parent pointers are not available.

Properties of threade binary tree:
  • if the left sub tree is empty, left link points to the in-order predecessor
  • if the right sub tree is empty, right link points to the in-order successor.



Fig: Threaded binary tree
 In-order traversals for the above binary tree is DBHEIAFCJG. As per the threaded binary tree rules , links are connected in the above image. The basic difference between binary tree and threaded binary tree is that in binary tree childs are null if there is no child associated with it, so there is no way to traverse back. Where as in threaded binary tree child nodes are assosiated with in-order successor or predessosor if no child assosiated with it. So back traversals is easy in this. There are many ways to implement the threaded binary tree. Below is the simple node structure for this.
struct node
{
    int info;
    struct node *left;
    struct node *right;
    //two boolian variables are true for only child nodes to make thread links. 
    bool llink,rlink; 
};

Thursday, March 8, 2012

What is smart pointer?

The main problems with pointers in C/C++ is handling memory managment. Most of the bugs related to memory leaks and dangling pointers. To overcome this C++ supports smart pointers. The smart pointer is a object similar to pointer. Smart pointer supports all basic operations like dereferencing(operator *), indirection (operator ->)  and below features which pointer doesn't support.

Automatic deallocation: Smart pointer deallocates/cleanup the allocated memory automatically using destructor.
Automatic initialisation: No need to initialise the pointer to NULL. smart pointer will take care using constructor
Handling Dangling pointers: One of the main problem in C/C++ is handling dagling pointer. i.e. accessing the pointer that is pointing to the another object which is already deleted. Smart pointers will take care about dangling pointers.

P.S: Simple example for the smart pointers in C++ is auto_ptr which is a part of C++ standard library. And the header file is .

Wednesday, March 7, 2012

How to declare/access the pointer variable inside the class in C++?

             Declaring the pointer variable inside the class is similar to normal C declaration only. While allocating the memory and access the variable will differ. It will be good to have a memory allocation in constructor and deallocation in destructor. See the sample code below for more clarity.

            In the below sample code, there is class ptr with one integer data member i and one integer pointer data member p. These are initialised in constructor using new for pointer variable. In destructor used delete for freeing the dynamic memory. For accessing the pointer data using the instance P and O as saind in main().

     *P->p gives the value of the variable and not P->*p. Where as P->p gives the address of the pointer variable. Similarly for object O, *O.p  gives the value of the variable and not O.*p. Where as O.p gives the address of the pointer variable.

using namespace std;

class ptr
{
    public:
        int i;
        int *p;
        ptr();
        ~ptr();
};

ptr::ptr()  // constructor
{
    i=10;
    p=new int;
    *p = 20;
}
ptr::~ptr() //destructor
{
    delete p;
}
int main()
{
    ptr *P=new ptr(); //dynamic instance

    cout<<"P->i is "<<P->i<<endl;  //accessing normal variable
    cout<<"P->p is "<<P->p<<endl;  // will get address of the poitner variable
    cout<<"*P->p is "<<*P->p<<endl; // accessing the pointer variable. P->*p is a invalid expression

    ptr O; //static instance

    cout<<"O.i is "<<O.i<<endl; //accessing normal int variable
    cout<<"O.p is "<<O.p<<endl; // will get the address of the int pointer
    cout<<"*O.p is "<<*O.p<<endl; //accessing the poiner variable. O.*p is a invalid expression
}


Output:

P->i is 10

P->p is 0xfda4030
*P->p is 20

O.i is 10
O.p is 0xfda4050
*O.p is 20

Tuesday, March 6, 2012

What is the difference between Struct and class in C++?

   The basic difference between struct and class in C++ is that by default all data member functions and member variabels are private in class  where as in struct it is public. Except this every thing is same for struct and class. All C++ concepts like polymorphism, inheritance etc works fine with struct also.

Basic example:

struct structClass
{
        int x; // defualt public
    public:
        structClass();
};

structClass::structClass()  // constructor
{
    x=0;
}

class classC
{
    int x; //defualt private
    public:
        classC();
};

classC::classC()  // constructor
{
    x=0;
}

int main()
{
    structClass sC;
    sC.x =10; // Legal as it is a struct and not a class
    classC cC;
//  cC.x = 10; // Illegal as it is a class and default specifier is private
}


Example for Inheritance:
struct base
{
    public:
        virtual void display()
        {
            cout<<"this is base class\n";
        }
};

class derived: public base
{
    public:
        void display()
        {
            cout<<"this is derived class\n";
        }
};

int main()
{
    base b1;
    derived d;
    base &b = d;
    b.display();
}
In the above sample code, base class is of type structure and derived class is of type c++ class. This also works fine in C++.

Monday, March 5, 2012

What is mutable variable in C++??

There are some cases where data members are declaring as const, and later want to change the value of the const variable.In C++, it is not legal to change the const value, by using mutable it is possible. This keyword can be applied to only non-static and non-constant data members.

Example for changing constant object data member:

class mute{

public:
int x ;
mutable int y;  // mutable variable declaration
mute() // constructor
{
x=10;
y=10;

}
};
int main()
{
const mute m; // constant object
//m.x=20; // Illegal cant change the data members in a constant object
m.y=20; // Legal, we can change , because its a mutable
}
For the above sampel code, there is class mute with one int and one mutable int data member functions. There is constant object for the class. If you try to modify the normal data members here it is x in line no.16, we will get compilation error. But we can modify the mutable  data , here it is y in line no.17.

Example for changing the constant function data:
class mute{

public:
int x ;
mutable int y;
mute()
{
x=10;
y=10;

}
void setValue(int a) const
{
//x=a; // Illegal, cant change the values in constant function
y=a; // legal, mutable data allowed to change in constant functions
}
};
int main()
{
mute m;
m.setValue(5);
}

In the above sample code, where we are changin the data members using constant functions. In line no.14, if you try to change the normal variable in constant function it will throuh an error. But if you see in line no.15 , its perfectly legal to change the mutable varaible in constant function.

Popular Posts