Saturday, September 28, 2013

Classes and Structures in c++

Class : It is an encapsulated unit containing the blue print of data members and member functions of an entity or concept in the real world.

This is the entry point into the OOPS paradigm.

Syntax : 
                class class_name {
                
                access_modifier :
                                       //data members and member function declaration

                access_modifier :
                                       //data members and member function declaration
                };


access modifier : it is a way to mention who can access the data members and member functions.

Now let's take an example and try to understand what is actually a class.

Let's take the example of a human being. Now, let's take into consideration the various aspects and behaviours of a typical human being. 
The data members associated with a Human Being is :

1> Name
2> Height
3> Weight
4> Complexity 
and many many  more....
what are the basic functionalities of a typical human being.

1> eat()
2> sleep()
3> walk()
4> sit()
5> speak()
and many many more....

Now say you want to implement the concept of a human being in a c++ program. What will you do??? or What is the best possible way to do it???
The answer is a class....



class HumanBeing {
private:
 float weight, height;
 char name[40], complexity[20];
public:
 void eat() {
  cout << "Eating !!!";
 }
 void sleep() {
  cout << "Sleeping !!!";
 }
 void walk() {
  cout << "Walking !!!";
 }
 void sit() {
  cout << "Siting !!!";
 }
 void speak() {
  cout << "Speaking !!!";
 }
};


Now, this is the basic blue print of a person class in c++. Now, you may be not knowing several things in the above program. But don't worry we will learn them one by one.

At first
Let's learn some of the basic principals of OOPs :

1> Encapsulation : The process of binding of data members and member functions together into a single unit is known as Encapsulation.

In other the above definition is nothing but a fancy way of saying that a OOPs
language needs a class(or a similar concept). Since, we can see in the above code block that the unit HumanBeing has bounded in a single unit the data members(Height, Weight, Complexion) and member functions(eat(), sleep(), sit()) into a single unit. 

2> Abstraction(Data Hiding) : The process of hiding the unessential data members and revealing only what is required is known as Abstraction.

This is implemented in c++ with the help of access modifiers. If you look closely at the code above you will notice the use of the word private: before declaring the data members. This tell the c++ compiler that these data members can be accessed only by the member functions of the class it is contained in.

3> Message Passing : It is the phenomenon of instructing an object to do a particular task.

This is achieved in c++ with the help of method call.

Method : The functions associated with an object is known as Methods. 
                

For example, if you want and object of the class HumanBeing to sit than you have to instruct it to do the same using the method sit().

Object : It is an entity with existence that has characteristics and behaviours of it self. 

or

It is a instance of a class.

New Text Document.

Now, let's understand this more clearly
















The above picture is showing the fact that the space for the object  is allocated when we instantiate the object and nothing is done in memory when the definition of the class is encountered by the compiler. The memory is allocated when we declare an object of the class for the first time.


Constructors : It is a special type of a function(not exactly a function) that is called when an object space is allocated for an object. 
    
   Purpose(Intended) : It is used to initialize the data members of a class.
    
   Syntax Rules required for declaring a Constructor :
   
   1> They must not have any return type(not even void. They are
mean functions and do not want to return anything).

   2> They must have the same name as the class.

   3> It may or may not have  Parameters.

   4> They can be overloaded(Yes you thought right... just like function).

   5> They can have any access specifier(But most preferably public).

    
   Let's see a example to make things more clear.....

#include<iostream>
#include<string>
using namespace std;
class Test {
 // a class without a constructor....
public :
 //data members...
 int a;
 string s;
 float f; 
 long l;
};

class TestWithConstructor {
 // a class with a constructor....
public :
 int a;
 string s;
 float f;
 long l;
 TestWithConstructor() {
  a = 0; s = "Nothing"; f = 0.0f; l = 12l;
 }
};
int main() {
 // this creates an object of type class 'Test' named 'myTest'
 Test  myTest; 

 //printing the values of the data members of the class Test...
 cout << "\n\n  Data Memebers of class Test : \n  ";
 cout << myTest.a << " : " << myTest.s << " : " << myTest.f << " : " << myTest.l;

 // this creates an object of type class 'TestWithConstructor' named 'myTestWithConstructor'
 TestWithConstructor  myTestWithConstructor; 

 //printing the values of the data members of the class Test...
 cout << "\n\n  Data Memebers of class Test : \n  ";
 cout << myTestWithConstructor.a << " :  " << myTestWithConstructor.s << " : " << myTestWithConstructor.f << " : " << myTestWithConstructor.l;
 cout << "\n\n  ";
 system("pause");
}

Output :

Let's understand it a bit more :









































There are three points we learn from this :

1> If we do not create a constructor than the c++ compiler does the work for you.
2> The Default constructor does not initialize any thing for you.
3>   The first thing that c++ does after allocating memory for an object is to call the constructor of the class.
4> It may be used for other initialization tasks that are pivotal to the working of the class.

Missconception :  It is used to allocate memory for the object.

                          C++ Structure

The only difference between a c++ class and a c++ structure is that in a structure the members are public by default.



struct Example {
 int a, b, c;
 string s;
 Example() {
  s = "Nothing"; 
  a = b = c = 0; // a nice use of multiple chained assignment statements
 }
};

though not much apparent by the syntax but the difference will be apparent when we see exactly how they are used.



Now lets talk about the access modifiers a bit.


Public : It is used when you want the whole outside world to know about that field and allow them to access and mutate that field (if the field is not constant that is).

Protected : will not be clear until we reach inheritance.

Private : it is this access modifier that is responsible for the feature abstraction(hiding from the cruel and dangerous world what is unnecessary and not safe).


struct ExampleStructure {
 int a, b, c;
 string s;
 ExampleStructure() {
  s = "Nothing"; 
  a = b = c = 0; // a nice use of multiple chained assignment statements
 }
};
class ExampleClass {
 //follows the most general guidelines of OOPS
 int a, b, c;
public :
 ExampleClass() {
 }
 // inside class(or implicit) definition
 int get_a() { 
  return a;
 }
 int get_b() {
  return b;
 }
 int get_c() {
  return c;
 }

 // outside class(or explicit) definition
 void set_a(int a); 
 void set_b(int b); 
 void set_c(int c); 
};

void ExampleClass::set_a(int a) {
 this->a = a;
}
void ExampleClass::set_b(int b) {
 this->b = b;
}
void ExampleClass::set_c(int c) {
 this->c = c;
}
void main() {
 ExampleStructure myStructure;
 ExampleClass myClass;
 //accessing data field members
 cout << "\n\n accessing fields of structure : " << myStructure.a << " " << myStructure.b << " " << myStructure.c;
 cout << "\n\n accessing fields of class : " << myClass.get_a() << " " << myClass.get_b()<< " " << myClass.get_c();

 //mutating data field members
 myStructure.a = myStructure.b = myStructure.c = 1;
 myClass.set_a(1); myClass.set_b(1); myClass.set_c(1);
}


the above example is an overly simplified definition of  a structure and class 
in c++.

First lets look at the class definition :

setter and getter :  Ask any one who has some experience of writing code any OOPS language and they will tell you that setters and getters are inseparable part of your coding arsenal.

So, what are they actually  you ask??

They are just normal member functions of a class who are assigned the specific task of accessing a data member of a class and setting their values.
Nothing else.

Getter  gets the values of the data members of a class.
       eg : get_a, get_b, get_c
Setter  sets the values of the data members of a class.
       eg : set_a, set_b, set_c

Now lets talk about this(???). Confused, don't be, I mean to say lets talk about the keyword 'this'. For this we have to dig a bit into the working of the c++ language. Lets suppose that we have more than one objects of a particular class and say we call a member function using one of the objects.
Now ask yourself how will the c++ compiler know exactly which object is used to call the member function(now please don't say by looking at the syntax because while running, the program is a sequence of bytes and not the well formatted multi-coloured text that you see at in your IDEs). 

Well the answer is the 'this' pointer. When we call a method by using an object. The 'this' pointer is passed as the first argument to the function. Of course it is done implicitly by the compiler and you are not aware of it.

Following is an image of an object in memory :
































Saturday, August 17, 2013

Pointers in C++

Motivation : The main reason pointers are used in C++ is because they are the memory managers.They are your only hope if you want  Dynamic Memory Allocation in your code (which is much more common than you believe ). Additionally you can save a considerable amount of time when you are working with large objects(will explain later). They are your buddies if you want to implement ADTs(what is ADT ? ) like tree, link list, queue and many many more. They can be used to implement efficient function calls. There are many more advantages of pointers. In short pointers give you supreme control over memory.

Beware : This is the first time i am including this heading because there are certain things that you all should know about Pointers before start using them : 
1> Venturing into unknown territory : Improper use of pointers can lead them to point to invalid locations(say a location that is currently in use by the OS) and hence the program will produce unexpected results and exceptions.

2> Code Readability : Too much use of pointers can lead to the code becoming a bit messy and hence can lead to maintenance problems.

3> Validity : Sometimes modifying a data structure(by say : inserting and deleting) may result in the pointers of that data structure to point to invalid locations.

4> Security : Sometimes pointers can be used to hack into C++ programs that is why C++ is not the language of choice when it comes to networking.



Definition : It is a variable that stores the memory address of variables of it's type.

Syntax : 
Declaration : 
               data_type *pointer_name;
Initialization : 
               data_type variable_name = val;
               pointer_name  = &variable_name;

let's look at the following pic to understand the syntax better:
1> This step is a simple variable creation named ia which is initialized to the value of 5.
2> This step creates a pointer of type int. Notice the * symbol for telling c++ that it is a pointer and not a normal variable. 
3> This is the most important line among the three lines lets look at it in more details in the pic below : 





Now, what do we do to extract the value of the variable that a pointer is pointing at. It's simple we use what is known as the 'value of' operator represented syntactically by '*'

Syntax : 
                 *(pointer_name);

Note : if you use (pointer_name) you get the address stored in the pointer.

look at the following simple program : 


#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int ia = 5;
 int *iptr = &ia;
 cout<<"\n\n\n  address of a = "<<iptr<<"value of a = "<<*iptr;
 getch();
}
output : 



pointer arithmetic : You can perform only one arithmetic operations between    pointers of same type(without using the '*' symbol) i.e. subtraction. It returns the no. of blocks between the address pointed by the  two pointers . where the size of block is the size of the data type of the pointer.

But you can do a lot more if you use the '*' symbol.
Now, lets look at a program to modify the value of variables using pointers.



#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int ia = 5, ib = 6;
 int *iaptr = &ia, *ibptr = &ib;
 cout<<"\n\n  ia + ib = "<<(*iaptr) + (*ibptr);
 cout<<"\n\n  ia - ib = "<<(*iaptr) - (*ibptr);
 cout<<"\n\n  ia * ib = "<<(*iaptr) * (*ibptr);
 cout<<"\n\n  ia / ib = "<<(*iaptr) / (*ibptr);
 getch();
}

output  : 





                        Arrays and Pointers

In c++ arrays and pointers have a striking resemblance. In fact the name of an array in c++ is nothing but a constant pointer having the same type as the array.
The operator [] can be defined in terms of pointer as follows :
array_name[i] = *(array_name + i) (this is the actual way in which the elements of the array are accessed in constant time)
note : so a[i] can be replaced with *(a+i) any and every where.

The following program shows how a basic array can be accessed using pointers 

#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int a[5];
 cout<<"\n\n  Enter Elements : ";
 for (int i = 0; i < 5; i++) {
  cin>>*(a+i);
 }
 cout<<"\n\n  The Elements are : ";
 for (int i = 0; i < 5; i++) {
  cout<<*(a+i)<<" ";
 }
        for (int i = 0; i < 5; i++) {
  *(a+i) = 2*3;
 }
        cout<<"\n\n  The Elements are : ";
 for (int i = 0; i < 5; i++) {
  cout<<*(a+i)<<" ";
 }

 getch();
}

So, actually what is the step (array_name+i) doing :


I hope the picture makes every thing clear. If not then in simple english the 
instruction (array_name + i) moves the pointer i steps ahead of the address pointed by the pointer array_name where the step length is equal to the size of the data type  of the array.

Note : remember that array names are constant pointers you cannot modify them i.e. operations like ++a, a++ are not allowed.


Types of pointers c++ supports several types of pointers : 
1> normal pointer.
2> pointer to constant variable.
3> constant pointer to a variable.
4> constant pointer to a constant variable.

look at the program to understand them clearly(i have skipped normal pointers).

#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int i = 10;
 const int ci = 10;
 const int *pci = &ci; //pointer to a constant integer(or atleast it thinks so)
 //allowed operations are:
 cout<<"\n\n  ++pci : "<<++pci;
 cout<<"\n\n   *pci : "<<*pci;
 //not allowed
 //++(*pci);
 int * const cpi = &i; //constant pointer to any type of integer
 //allowed operations are:
 cout<<"\n\n  ++cpi : "<<++(*cpi);
 cout<<"\n\n   *cpi : "<<*pci;
 //not allowed
 //++cpi;
 const int * const cpci = &ci; //constant pointer to constant integer(or atleast it thinks so)
 //allowed operations are:
 cout<<"\n\n   *cpi : "<<*cpci;
 //not allowed
 //++(*cpci);
 //++cpci;
 //++cpi;
}

Now, lets look at 2d Arrays : 2D Arrays  have two kinds of implementation in memory. 
1> Row Major :  Elements are arranged in rows and the rows are kept after one another.
2> Column Major : Elements are arranged in columns and the columns are kept after one another.


Now, lets look at a more detailed pic of Row Major representation of a 2D Array.
When we declare a 2D array without using dynamic memory allocation like :

int arr[3][3];

you may think that arr is a double pointer(**arr) but it is actually not so. It has been made to look like a double pointer and have a syntax like double pointer. So, actually what is it :

The above diagram looks exactly like a 1D array. So, what is the difference between this and a 1D array :
Well it is the way the '+' operator behaves under different conditions.

Here the '+' has different meaning when used with (array_name) and 
*(array_name)

look at the following pic to understand this whole thing clearly :



when you use the '+' with the array_name it skips the whole row and when used with *(array_name) it provides the more rational behaviour as you expect from a pointer.

if array_name was a double pointer then :
 array_name+2 = address(array_name) + 2*sizeof(data type of pointer)
but that is not the case so it is not a double pointer.



                      Dynamic Memory allocation

Motivation : Let's say you are writing a library management system and one of the features of the software requires you to add members dynamically, i.e. you cannot know the number of users before hand. This is a serious problem because if you take a look at all the language tools we have studied so far none of them has the capability to solve this problem. So c++ provides what is known as  Dynamic Memory allocation.

Definition : This is the process of allocating memory from 'the heap' during the runtime of the program as and when required.
To understand what is 'the heap' lets look at the following pic :



This is a Memory layout of  a process(What is a Process?).
So, the heap is a region of memory allocated to every program by the OS. So, that memory can be extracted from it during runtime as and when required.

The tool provided by C++ to manage heap memory is the 'new' and the 'delete' operator

Syntax : 
               data_type *pointer_name = new data_type ; //for single block
               data_type *pointer_name = new data_type [no. of blocks]; //multiple blocks

look at the pic below for a better understanding :





























The 'new' operator returns a pointer having the type  you requested it to allocate. So, without the use of pointers you can never allocate memory dynamically. 
The 'new' operator can also take an additional argument in '[]' which mentions the no. of blocks you want to allocate. The blocks have contiguous allocations in memory.

The following program creates a 1D Array :

#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int N, *array;
 cout<<"\n\n  Enter the size of Array : ";
 cin>>N;
 array = new int [N] ; //creating the 1D array using the new operator
 cout<<"\n\n  Enter Array Elements : ";
 for (int i = 0; i < N; i++) {
  cin>>*(array+i);
 }
 cout<<"\n\n  Array Elements are : ";
 for (int i = 0; i < N; i++) {
  cout<<*(array+i)<< " ";
 }
 getch();
}

In the above program we use the 'new' operator to allocate N blocks of int type. 

The Delete operator : Like the name suggests it is used to deallocate the memory block that is allocated with the help of  the 'new' operator.

Syntax : 
               delete pointer_name; //for a single block.
               delete[] pointer_name; //for a collection of blocks.

#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int N, *array;
 cout<<"\n\n  Enter the size of Array : ";
 cin>>N;
 array = new int [N] ; //creating the 1D array using the new operator
 cout<<"\n\n  Enter Array Elements : ";
 for (int i = 0; i < N; i++) {
  cin>>*(array+i);
 }
 cout<<"\n\n  Array Elements are : ";
 for (int i = 0; i < N; i++) {
  cout<<*(array+i)<< " ";
 }
 delete[] array;
 getch();
}

This is the same program as the one above it with the only difference of the 
use of 'delete'  operator. We have used the collection version of the delete operator as we want to delete the whole array.

The Memory Leak : What actually is a memory leak???
 It is nothing but the phenomenon where the allocated memory is not cleaned up properly.just imagine a software that allocates  memory on the go. Now, let'st  assume  that there is memory  leak  in the program. which keeps  on eating the memory available to the program and after some time you will run out of memory and the program will complain out of memory. This problem is more severe if your program is huge and cannot be fitted in the memory at once  (like games). It will be a disaster. So, memory management is an important part of every C++ software. 

look at the program below that goes on allocating memory without deallocating it.
#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int N = 100000, *array;
 while(1) {
  cout<<"\n Allocating : "<<100000*4/1024<<" KB memory";
  array = new int [N];
 }
 getch();
}


Below is the snippet of the output :





































What you see here is known as an Exception(we will study about them later). If you look at the window on the right hand size it shows bad_allocation exception that means the call to allocate a new block of memory failed. 

Now, lets look at the revision(memory managed) of the above code with an additional call to delete to deallocate the allocated space.

#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int N = 100000, *array;
 while(1) {
  cout<<"\n Allocating : "<<100000*4/1024<<" KB memory";
  array = new int [N];
  delete[] array;
 }
 getch();
}

What i showed above is a trivial case of memory management. There are certainly many more examples of memory leak where it is very difficult to even detect the memory leak let alone correct it.


Beware of the Dangling Pointer :  The dangling pointer is a pointer which refers to a location that has been invalidated by some operation in the program but despite all this it still continues to point at the invalid location which now belongs to the operating system and any attempt to modify the contents of the location will lead to unpredictable and unknown behaviour.

look at the program below to understand the concept more clearly.

#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int *ia = new int;
 *ia = 5;
 cout<<"\n\n  ia : "<<ia;
 cout<<"\n\n  *ia : "<<*ia; //correct accessing the content of a valid location
 cout<<"\n\n  ++(*ia) : "<<++(*ia); //correct modifying the content of a valid location
 delete ia; // the block is deallocated but the pointer ia is still pointing to the invalid location
 cout<<"\n\n  after the call to delete : ";
 cout<<"\n\n  ia : "<<ia;
 cout<<"\n\n  *ia : "<<*ia; //incorrect accessing the content of a invalid location
 cout<<"\n\n  ++(*ia) : "<<++(*ia); //incorrect modifying the content of a invalid location
 getch();
}

Below is the snippet of the ouput :



As you may have noticed, that after the call to delete. The content of the ia pointer becomes invalid. So, ia becomes a dangling pointer. 

Solution : Make ia a 'NULL' pointer after the call to delete.

Syntax : 
               pointer_name = NULL;

note : NULL is a macro defined  in header file std  and it has a value of 0. Making a pointer point to 'NULL' means it is pointing to nothing.

look at the program to see the solution in action.
#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int *ia = new int;
 *ia = 5;
 cout<<"\n\n  ia : "<<ia;
 cout<<"\n\n  *ia : "<<*ia; //correct accessing the content of a valid location
 cout<<"\n\n  ++(*ia) : "<<++(*ia); //correct modifying the content of a valid location
 delete ia; // the block is deallocated but the pointer ia is still pointing to the invalid location
 ia = NULL; //make ia point to null so that it does not point to the invalidated location
 cout<<"\n\n  after the call to delete : ";
 cout<<"\n\n  ia : "<<ia;
 cout<<"\n\n  *ia : "<<*ia; //incorrect accessing the content of a invalid location
 cout<<"\n\n  ++(*ia) : "<<++(*ia); //incorrect modifying the content of a invalid location
 getch();
}
here is the snippet of the output :






















































Thus this simple initiative of making the ia pointer point to NULL pays in the long run. Now you may argue that what is the use of this step if it results in an exception being thrown. It has a huge advantage and it is the fact that it is throwing an exception an telling you that you have done something that you should not have done. As a result you can correct your mistake. Incase of large software projects this is a huge advantage(as searching the error may take a lot of time).


Creating a 2D Array with the new operator : When we create a 2D array with the help of new operator it will looks different in memory and also the underlying concept of how it works is different. We really require a double pointer here.

Syntax : 
          data_type **pointer_name = new data_type* [NUMROWS];
          for(int i = 0; i < NUMROWS; i++)
                 pointer_name[i] = new int [NUMCOLUMNS];

Note : This is one way  of doing it. You may do in any other way that you feel comfortable.
NUMROWS : number of rows.
NUMCOLUMNS : number of columns.  

Array of pointers  : It is nothing but an array where every element of the array is a pointer.

Note :  The 'array_name' of an array of pointers is a double pointer since it points to the base address of the array i.e. it holds the address of the first element of the array which is a pointer.

What we did at first was create an array of pointers having [NUMROWS] elements. In the next step we iterate through each element of the array and assigned to them  an array of integers  using 'new' having [NUMCOLUMNS] elements.
So, if this seems complicated do not worry the following diagram will make it clear :

Now, lets try to understand the access mechanism. With the pic below.
























So, we see that though the behaviour of dynamic 2D array and the one created statically are same. But their underlying principle and working mechanism is entirely different.

let's look at a program to understand it more carefully.


#include<iostream>
#include<conio.h>
using namespace std;
int main(){
 int **array, NUMROWS, NUMCOLUMNS;
 cout<<"\n\n  Enter Rows : ";
 cin>>NUMROWS;
 cout<<"\n\n  Enter Columns : ";
 cin>>NUMCOLUMNS;
 array = new int* [NUMROWS]; 
 for (int i = 0; i < NUMROWS; i++) {
  array[i] = new int[NUMCOLUMNS];
 }
 cout<<"\n\n  Enter Array Elements : ";
 for (int i = 0; i < NUMROWS; i++) {
  cout<<"\n\n  Enter row no. "<<i<<" : ";
  for (int j = 0; j  < NUMCOLUMNS; j ++) {
   cin>>*(*(array+i)+j); //equivalent to a[i][j]
  }
 }
 cout<<"\n\n  Array Elements are : ";
 for (int i = 0; i < NUMROWS; i++) {
  cout<<"\n\n  ";
  for (int j = 0; j  < NUMCOLUMNS; j ++) {
   cout<<*(*(array+i)+j)<<" "; //equivalent to a[i][j]
  }
  cout<<"\n";
 }
 getch();
}

Snippet of the output : 


Function Pointer : A function pointer is a pointer that can point to a specific type of function and it can be used to mimic the call to a function.

Syntax : 
                return_type (*function_pointer_name) (arguments);
                 function_pointer_name = & function_name
               


#include<iostream>
#include<conio.h>
using namespace std;
double square(double x)  {
 return (x*x);
}
double cube(double x) {
 return (x*x*x);
}
double (*functionPointer)(double ); // function pointer that can point to a function that has return type double and takes an argument of type double.
int main(){
 int choice;
 double n;
 cout<<"\n\n  Enter Choice (1 for square) and (2 for cube) : ";
 cin>>choice;
 switch(choice) {
 case 1 :
  cout<<"\n\n  Enter n : ";
  cin>>n;
  functionPointer = &square;
  cout<<"\n\n  square ("<<n<<") : ";
  break;
 case 2:
  cout<<"\n\n  Enter n : ";
  cin>>n;
  functionPointer = &cube;
  cout<<"\n\n  cube ("<<n<<") : ";
  break;
 default :
  cout<<"\n\n  Wrong option!!";
 }
 cout<<functionPointer(n);
 getch();
}