Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/articles/cpp-tutorials/)
-   -   All about const in C++ (http://www.go4expert.com/articles/const-cpp-t19261/)

Mridula 1Sep2009 17:58

All about const in C++
 

Introduction



This article talks about all different usage of const qualifier in C++.

Background



Declaration:

Named constant or const variables

const int PI = 3.14

Declares a named constant called PI, which can be used later in the program where ever we want to use the value 3.14.

This is similar to #define macro, but using const is better as it is understood and used by the compiler itself and not just simple substitution in the program which is done by preprocessor on using #define.

const with pointers:

Here one has to be careful in using const to know whether it is used to determine the
  1. Pointer as constant or
  2. The Data what it points is constant or
  3. Both i.e. both Data and Pointer are constant.

To declare a pointer that is pointing to a constant interger

const int *ptrToConstData1;
int const *ptrToConstData2;


Here, we cannot change the data it is pointing to.

To declare a const pointer that is pointing to an integer


int * const ptrIsConst;

This has to be declared and initialised and cannot be changed later to point to some other variable.

To declare a const pointer pointing to constant integer

const int * const ptrAndDataCnst;

Here both pointer and data are constant. As it is also a constant pointer, it has to be initialised while declaring itself.

The code



Code: Cpp

#include<iostream.h>

int main()
{
  //declaring a named constant
  const float PI = 3.14;
  cout<<"PI Value is: "<<PI;
  cout<<endl;

  //pointer to constant integer
  int i = 123;
  int const *ptrToConstData;
  ptrToConstData = &i;
  cout<<*ptrToConstData;

  //cant change as it is pointing to const value
  //*ptrToConstData = 321;
  //

  //constant pointer
  int j = 123;
  int * const ptrIsConst = &j;
  cout<<endl;
  cout<<*ptrIsConst;
 
  //cant change as it is a const pointer
  //ptrIsConst = &i;


  //constant pointer pointing to constant integer
  int k = 123;
  const int * const ptrAndDataConst = &k;
  cout<<endl;
  cout<<*ptrAndDataConst;

  cout<<endl;

  return(0);
}

output:
-----------
PI Value is: 3.14
123
123
123


const Data Member:

Any const data members of a class has to be initialized and has to be done in the initilizer list of the class's constructor. Only static const data members can be intialized inside the class declaration.

The code



Code: Cpp

#include<iostream.h>

class Abc
{
  const int myInt_m;
  static const double myDouble_m = 100.53;

  public:

    //We cannt initialise the const members inside the constructor as below
    /*Abc(int j=0)
    {
      myInt_m = j;
      cout<<"Value of myInt is : "<<myInt_m<<endl;
    }*/


    //we have to initialise it in initializer list as below
    Abc(int j =0):myInt_m(j)
    {
      cout<<"Value of myInt_m is : "<<myInt_m<<endl;
      cout<<"Value of myDouble_m is : "<<myDouble_m<<endl;
    }
};

int main()
{
  Abc abc(10);
  return(0);
}

output:
----------
Value of myInt_m is : 10
Value of myDouble_m is : 100.53


Return by const value:

Return by const is meaningful in case of returning:-

- const strings and arrays from functions as they are implemented as pointers. This is to avoid the program altering their lValue and getting crash.

- If a function is returning any user-defined data types like class objects. Where as It does not make sense returning const to a built-in types, as compiler anyway takes care of it.

In above cases by making that function returning a const will prevent using that returned value as an lValue in program as it will be a compier error. Otherwise, it will allow using that returned value as lValue.

The code



Code: Cpp

#include <iostream.h>

char* func1()
{
  return ("Mridula");
}

const char * func2()
{
  return ("Mridula");
}

int func3()
{
  return (1);
}

class Abc
{
  int myInt;

  public:
    Abc(int j=0):myInt(j)
    {
      cout<<"Value of myInt is :"<<myInt<<endl;
    };
};


Abc func4()
{
  return Abc();
}

const Abc func5()
{
  return Abc();
}

int main()
{
  //Trying to modify will lead to segmentation fault
  //Func1()[1] = 'K';
 
  //Trying to modify will give a compiler error now
  //Func2()[1] = 'K'; 
 
  //Compiler will anyway prevent using it as an lValue here as it is built-in data type
  //func3() = 3;

  //Compiler will allow using func4 as lValue
  func4() = Abc(5);

  //Compiler will prevent using func5 as lValue now
  //func5() = Abc(10);

  return (0);
}

output:
---------
Value of myInt is :0
Value of myInt is :5


const variable as an argument:

To make sure, preventing the data that is passed as argument, whether it could be a reference or pointer variable (which was sent to avoid sending by value as copying in case of big user defined data is costly), getting aletred inside the function or callee, then we can send that data by const qualifier.

The code



Code: Cpp

#include<iostream.h>

void func1(int &j)
{
  //function is modifying it
  j = 100;

  cout<<j;
  cout<<endl;
}

void func2(int const &j)
{
  //cant modify the value, compiler error
  //j= 10;

  cout<<j;
  cout<<endl;
}

void func3(int j)
{
  //declare a reference to int and reference to the sent data
  const int &k = j;

  //altering this value would be a compiler error
  //k = 10;

  cout<<j;
  cout<<endl;
}

int main()
{
  int k;
  k= 10;

  func1(k);

  k=20;
  func2(k);

  k=30;
  func3(k);
 
  return (0);
}

output:
---------
100
20
30


As shown in the example, to ease the burden of caller not sending data as const, we can even implement inside the function by making a const reference to the sent value and then prevent alering it.

const Member Functions:

Declaring as below makes that method as const

int myInt() const

it means, function is not allowed to modify any of the data members of that class object. Normally, get accessors are written as const methods.

The code



Code: Cpp

#include<iostream.h>

class Abc
{
  int myInt_m;
  int k;
 
  public:

    Abc(int j=0):myInt_m(j)
    {
      cout <<j;
      cout<<endl;
    }

    int myInt() const
    {
      //trying to modify this will lead to compiler error
      //myInt_m = 20;

      cout<<myInt_m;
      cout<<endl;

      return(myInt_m); //---
    }
};

int main()
{
  int k;
 
  Abc abc(100);
  k = abc.myInt();
 
  return(0);
}

output:
--------
100
100


const int*const myFunction(const int*const&)const


This one is an example of a const method, that will return a constant pointer, pointing to a const integer, also it does not alter any of passed arguments to it.

Related terms to const

operator const_cast < >

This is used to remove the constant quality of a variable or object.

The code


Code: Cpp

#include<iostream.h>

void sqrtVal(const int* a)
{
  int * j = const_cast<int *> (a); //cast away const-ness
  *j = (*j)*(*j);

  cout<<"sqrtVal :"<<*j<<endl;
}

int main()
{
  cout<<"Case 1: where Integer variable is not explicitlly associated with const"<<endl;
  int a = 10;
  cout<<"Before the value of a :"<<a<<endl;

  const int *k = &a;
  sqrtVal(k);
  cout<<"After the value of a :"<<a<<endl<<endl;

  cout<<"Case 2: where Integer variable is explicitly associated with const"<<endl;
  const int b=10;
  cout<<"Before the value of a :"<<a<<endl;

  const int *l = &b;
  sqrtVal(l);
  cout<<"After the value of a :"<<b<<endl<<endl;
 
  return(0);
}

output:
----------
Case 1: where Integer variable is not explicitlly associated with const
Before the value of a :10
sqrtVal :100
After the value of a :100

Case 2: where Integer variable is explicitly associated with const
Before the value of a :100
sqrtVal :100
After the value of a :10


As shown in the above example, case-1 we can cast away the constness of a variable or object, that is not explicitly declared with const qualifier. Where as in case-2, if we try to cast away constness of a variable or object that has been explictly declared as const, results in undefined bahaviour.

Also, below is another example showing the usage of const_cast in a class's const member function.

The code


Code: Cpp

#include<iostream.h>

class Abc
{
  int myInt_m;

  public:
    Abc(int j=0):myInt_m(j)
    {
    }

    void modifyConstFunc(void) const
    {
      cout<<"Initial value of myInt_m: "<<myInt_m<<endl;

      //try to modify myInt_m
      const_cast <Abc *> (this)->myInt_m--;

      cout<<"Modified value of myInt_m :"<<myInt_m<<endl;
    }
};

int main()
{
  Abc abc(10);
  abc.modifyConstFunc();
 
  return(0);
}

output:
--------
./a.out
Initial value of myInt_m: 10
Modified value of myInt_m :9


Here, in this example, const_cast allows to modify the member of a class in a constant member function.

mutable keyword

Declaring a member variable as mutable allows that particular variable to be modified in a const member function. It means, it allows the declared member of a constant object to be modified.

This concept is used, when most of the data members of a class are kept const, but few need to be updatable, then declare those updatable members as mutable.

The code


Code: Cpp

#include<iostream.h>

class Employee
{
  const int myId_m;
  const char *myName_m;
  mutable double mySalary_m;

  public:
    Employee(const int id,
          const char* name,
          double salary):
          myId_m(id),
          myName_m(name),
          mySalary_m(salary)
    {
      cout<<"Employee details ..."<<endl;
      cout<<"------------------------"<<endl;
      cout<<"Id: "<<myId_m<<endl;
      cout<<"Name: "<<myName_m<<endl;
      cout<<"Salary: "<<mySalary_m<<endl;
      cout<<endl;
    };

    const int getMyId(void) const
    {
      return (myId_m); //---
    }

    const char *getmyName(void) const
    {
      return(myName_m); //---
    }

    double getSalary(void) const
    {
      return(mySalary_m);
    }

    void increment(int id, double salary) const
    {
      //confirm the id and update the salary
      if (id == myId_m)
      {
        mySalary_m += salary;
      }
    }
};

int main()
{
  Employee emp(10, "Mridula", 10000);

  emp.increment(10, 5000);
  cout<<"Updated salary :"<<emp.getSalary()<<endl<<endl;

  return(0);
}

output:
----------

Employee details ...
------------------------
Id: 10
Name: Mridula
Salary: 10000

Updated salary :15000


References



Also Refer:

Constant and pointer
http://www.go4expert.com/showthread.php?t=1578

mayjune 2Sep2009 19:51

Re: All about const in C++
 
Very nice article, As expected from you....

Mridula 3Sep2009 12:44

Re: All about const in C++
 
Many thanks mayjune !!
Then please vote this artcile, if it gets nominated in the August month's competetion!!

mayjune 4Sep2009 01:03

Re: All about const in C++
 
But you posted it in September? It'll get selected in September na?

michaelsm 4Sep2009 17:23

Re: All about const in C++
 
Thanks for the very nice article and very very thanks for the pasting a code in it.

Mridula 5Sep2009 20:25

Re: All about const in C++
 
@mayjune
For september's competetion :-)

many thanks michaelsm

mayjune 5Sep2009 20:29

Re: All about const in C++
 
Cool

matrix_jc2001 15Sep2009 08:57

Re: All about const in C++
 
Guys i need your help T_T my professor gave me a problem and i don't know how to do it, pls help me

"Creat a program that will compute for the grade of students and its equivalent grade point.. the formula for computing grade is GRADE=10%, ASSIGNMENT=20%,Seatwork=30%,Quiz=40%
Note that there are 2 assignment,quiz,and seatwork given

Equivalent grade point:
1.0 = 99-100
1.25 = 96-98
1.5 = 93-95
1.75 = 90-92
2.0 = 87-89
2.25 = 84-86
2.50 = 81-83
2.75 = 78-80
3.0 = 75-77
5.0 = below 75

thanks, i hope you can help me T_T God Bless!

shabbir 15Sep2009 09:29

Re: All about const in C++
 
matrix_jc2001, Do not jump into any thread with that and I see you already have a thread for it.

shabbir 3Oct2009 17:07

Re: All about const in C++
 
Nomination for Article of the month - Sep 2009 Started. Nominate this article.


All times are GMT +5.5. The time now is 20:12.