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 Pointer as constant or The Data what it points is constant or 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: #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: #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: #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: #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: #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: #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: #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: #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
Many thanks mayjune !! Then please vote this artcile, if it gets nominated in the August month's competetion!!
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!
hi, I have a doubt here regarding const data members. I guess the static const data members can be initialized inside a class only if they are integral or enumeration type. Please correct me if i am wrong.
Hi patelpradeep, Nothing like that. We can initilize all data types of "static const". Thats why as you can see, purposefully I have taken the example of "double" data type in the article. All the programs what has been put in the article are compiled successully and result also given for the same. thanks mridula.
Nomination Closed and Voting started for Article of the month - Sep 2009. You can vote for this Article