CPP

Classes in C++

There are two important components of an object, one is data member and other is member functions which operate upon the data. We can use malloc or new operators to allocate memory to an object. However using new is considered better than malloc, as malloc returns void pointer ot is necessary to explicitly typecast ot into an appropriate typeof pointer. This gets completely avoided when we are using new operator. While using new, constructor gets called automatically, which is not in the case of malloc and new being an operator, can be overloaded.

In C++, we can define default values for the parameters, which is true for constructors as well.
For example
#include <iostream>

using namespace std;

class A
{
    public: int i,j,k;
    public: A(int _i = 0, int _j = 0, int _k = 0)
    {
        i = _i;
        j = _j;
        k = _k;
    }
};

int main()
{
   A a(1);
   cout<< a.i << a.j << a.k; //print 100
   A a1(1,2);
   cout<< a1.i << a1.j << a1.k; //print 120
   A a2(1,2,3);
   cout<< a2.i << a2.j << a2.k; //print 123
   
   return 0;
}


Similar to new, In C++ there is an operator to deallocate the memory used by object, called delete operator. Delete operator not only deallocate memory but also calls the destructor of the class whose object is being destroyed.

Access specifiers: In C++ we have three access specifier, public, protected and private. public data members or member functions can be access from anywhere (i.e. from inside the class and outside the class. Private members can only be access within the class. we define members protected to specify where all these members can be inherited.

We can define the member functions outside the class, but if they defined outside, then there has to be a declaration of the member function present inside the class.
For example
#include <iostream>

using namespace std;

class A
{
    public: void sum(int, int);
};

void A::sum(int a, int b)
{
    cout<< a + b;
}

int main()
{
   A a;
   a.sum(3,4); //to call a member function from outside the class, we need to have an object of the class.
   
   return 0;
}


In C++, we can also declare an array of objects, for example

#include <iostream>

using namespace std;

class A
{
    public: void sum(int, int);
};

void A::sum(int a, int b)
{
    cout<< a + b;
}

int main()
{
   A a[2] = { A(), A()}; //to declare an array of A objects
   a[0].sum(3,3);
   a[1].sum(2,3);
   
   return 0;
}


C++ also supports const data members.

#include <iostream>

using namespace std;

class A
{
    public: A():i(20) //we can assign value to const in constructor
    {
        //i = 20; //we cannot assign value to const here, as this will raise error
    }
    const int i = 10; //we can assign value to const during declaration
    public: void sum(int, int);
};

void A::sum(int a, int b)
{
    cout<< a + b + i;
}

int main()
{
   A a;
   a.sum(3,3);
   
   return 0;
}


When you want to group some stuff together and declare one or more instances of it, but don't need to refer to that type by name, then anonymous classes can be used.
For example
#include <iostream>

using namespace std;

class //this is an anonymous class
{
    public: void sum(int a, int b)
    {
        cout<< a + b;
    }
} a; //this is an object of this class

int main()
{
   a.sum(3,3); //calling sum function of anonymous class
   
   return 0;
}


Now, consider the following example using typedef keyword. We have given an alias name to "ThisIsMyClassWhichProvidesSumFunctionality" class and then used the same name instead of long name used to define the class.
#include <iostream>

using namespace std;

class ThisIsMyClassWhichProvidesSumFunctionality
{
    public: void sum(int a, int b)
    {
        cout<< a + b;
    }
};

typedef ThisIsMyClassWhichProvidesSumFunctionality ClassA; //giving an alias name to "ThisIsMyClassWhichProvidesSumFunctionality"

int main()
{
    ClassA a;
    a.sum(3,3);
    
    return 0;
}


Memory Leak: When we allocate memory dynamically but somehow lose the way to reach that memory then it is called as memory leak

For example
#include <iostream>

using namespace std;

void function()
{
    int *p = new int;
}

int main()
{
    function(); //after this function call, memory gets leaked, as we have assigned memory to p, but never deallocated the memory
    return 0;
}


Dangling pointers: Suppose we have a chunk of memory and store its address in a pointer. If this chunk of memory is freed and if the pointer continues to point to that location, the pointer is said to be a dangling pointer.
For example
#include <iostream>
using namespace std;
int main()
{
    int *p;
    int *q = new int;
    p = q;
    delete q;
    //now here, pointer p is a dangling pointer, as memory assigned to q is freed in the above line.
    return 0;
}


We can also create an object of an empty class and size of objects of empty class is one byte.

There is a special pointer in C++, this pointer. this pointer is created when a member function (non-static) of a class is called.
For example
#include <iostream>

using namespace std;

class A
{
    public: int i;
    public: A(int i)
    {
        this->i = i;
    }
    public: int multiply(int a)
    {
        return a * this->i;
    }
};

int main()
{
    A a(2);
    cout<< a.multiply(5);
    return 0;
}


Following is an example of using pointer to an object of a class.
#include <iostream>

using namespace std;

class A
{
    public: int i;
    public: A(int i)
    {
        this->i = i;
    }
    public: int multiply(int a)
    {
        return a * this->i;
    }
};

int main()
{
    A *a = new A(2);
    cout<< a->multiply(5);
    return 0;
}


One thing to note is that, we cannot call destructor explicitly in C++, they gets called automatically when an object is about to get destroyed. For example, when delete operator is called.
#include <iostream>

using namespace std;

class A
{
    public: int i;
    public: A(int i)
    {
        this->i = i;
    }
    public: int multiply(int a)
    {
        return a * this->i;
    }
    ~A() //destructor
    {
        cout<< "deleted";
    }
};

int main()
{
    A *a = new A(2);
    cout<< a->multiply(5);
    delete a; //this statement will call the destructor ~A()
    return 0;
}


Note: free() does not call the destructor, as free only deallocates memory, but does not call the destructor.
Add Comments :

Login

Register