Skip to main content

Constant members of a Class

A constant  is a value which can not be modified. As in C, we can have literal constants using #define and we can have enums and we can define a variable to be const.  Let us look at const variables here.

By declaring a variable as const, we ensure that it is not modified accidentally. Any modification to a constant will give a compilation error.

A const should always be initialized while defining.

In the program below,  assignment to pi gives a compiler error because pi is defined as const and code is trying to modify this.


int main()
{
 const float pi = 22.0/7;
 int radius = 12;
 radius++;/*ok*/
 pi = 3.14;/*error*/
}

 Constant parameters to functions

Even function parameters can be constant. We have earlier discussed that making a reference parameter as constant will avoid the function from accidentally modifying the argument.

void printnum(int & n)
{
 cout<<n++;
}
void printnum2(const int & n)
{
 cout<<n++;/*error*/
}
int main()
{
 int a = 10;
 printnum(a);
 cout<<a;/*prints 11*/
 printnum2(a);
}

In printnum() function, n++ will increment the parameter which may be unintentional but is not caught by the compiler. But in printnum2(), n++ gives a compiler error, because the parameter is a constant reference, and it can not be modified.

Unless your function needs to change the reference parameter,  make the parameter as a constant reference.

Next let us consider how to define and use constant members of a class.

Constant Data Members of a class

A class can have constant data members by using keyword const in declaration. Such members can not be modified after the object is created.


The question arises - how do we initialize such const members?

class A
{
 const int n;
public:
 A();
};

A::A() 
{
 n= 10;/*error*/
}

Initializing const data members must be done using member initializer list. Because const data can not be assigned even within a constructor body.

class A
{
 const int n;
public:
 A();
};
A::A():n(10)
{
}

As can be seen in the example,  const member n is initialized in member initializer list.
If a class has a const data member
  1. write a constructor for that class
  2. in the constructor, initialize the const member using member initializer list
Constant Objects
 

We can define a constant object. Once defined, the state of this object can not be modified. Its data members can not be modified either directly or using member functions.
class A
{
 int a;
public:
 void print();
 void seta(int m){a = m;}
};
void A::print()
{
 cout<<a;
}
int main()
{
 const A obj1; 
 obj1.seta(12);//error
 obj1.print();//error
}

The object obj1 is a constant object and can not be modified. So obviously it can not call the function seta(). But it can not even call print() function which does not modify data members. Why?

Because compiler allows constant object to call only constant member functions - i.e. functions which can not modify state of the object.

Constant functions


A constant member function is a function which guarantees that it does not modify the state of the object i.e. it can not modify any data member.

A const function is written by adding keyword const after the parameter list. This const key word should be added both in declaration of the function and definition.

class A
{
 int a;
public:
 void print() const;
 void seta(int m){a = m;}
};
void A::print() const
{
 cout<<a;
 // a = 0;/*invalid*/
}
int main()
{
 const A obj1;
 obj1.print();//valid
 //obj1.seta(12);//error
 A obj2;
 obj2.seta(12);//valid
 obj2.print();//valid
}

As you can see in the modified code above, print() function, which is now a const function, is not allowed to change a  - the data member. Trying to modify a in print() function gives a compiler error.

 obj1 which is a constant object can call const function viz. print(). It can not call seta() function because it is not const function.

But a non-constant object
obj2 can call both const and non-const function.

We can overload a function using constantness. That is there can be two member functions which are similar but one is const and other is not const.


class A
{
public:
    void print();
    void print() const;
};




Mutable members:

Even from a constant object, mutable data members can be modified and they can be changed even inside a const functions.

class A
{
 mutable int num_accessed;/*mutable member*/
 int b;
public:
 /*other code*/
 void print() const;
};

void A::print() const
{
 cout<<num_accessed<<" "<<b;
 num_accessed++;/* valid. the member is mutable*/
}


In the code above, num_accessed is incremented within a const function and the program would compile without errors.

Comments

Popular posts from this blog

Ten questions in C/C++

Let us see some questions in C and C++ Write printf statement in C to print - I got 98% in Maths Can you execute a function before main() in C? If yes, how is it done? Can you write a program to find if a number is even without using modulo operator? How do you define a data member which is common to all objects of a class in C++? Can we have a single constructor for a class, but still create objects from the class passing zero/one and two parameters? What problems might occur if a class has no default constructor? Is the following statement correct? fprintf(stdout,"Hello world");   Why do we use the following statement in C++ program? using namespace std;  Can you write a single statement to check if the number is a power of 2?  What does the following statement mean in C/C++?4 if(a) b++;    So we have 10 questions. How many of these can you answer?   Do you need more questions in C and C++?    You can find t...

It is a constant

In good old days, C programmers would use preprocessor directive to define constants. e.g. #define s 10 But we know now that, as compiler never gets to see these, preprocessor statements are error prone. Hence we have const s. A constant - defined with keyword const promises that this entity is never going to change. And if we accidentally modify a const, compiler throws an error. Let us look at an example. #include<iostream> using namespace std; int main () { int a = 10 ; const int b = 12 ; a ++ ; b = 18 ; } When we compile this program, compiler tells us that default.cpp: In function ‘int main()’: default.cpp:8:7: error: assignment of read-only variable ‘b’      b = 18; So it is catching the error that we are trying to modify a const. Whenever a local variable or parameter need not be modified, declare it as a const.  Yes, we can make even parameters as constant. We can make objects constant or even me...

Abstract class

 If we can not create any objects of a class, then it is called an abstract class. A class is made abstract by adding at least one pure virtual function to it. Pure virtual function A function is said to be a pure virtual function , if it has no definition but has only declaration. Pure virtual function is defined with the keyword virtual and followed by return type, function name and "=0". class Shape { public: virtual void printarea() =0 ; }; int main () { Shape obj1; //error } Here printarea() function of Shape class is a pure virtual function as it has no body. To make a function as pure virtual function, you should use =0 at the end of virtual function declaration Abstract class When a class has at least one pure virtual function, it is incomplete and no objects can be created from that class. Such a class is called an abstract class . In the earlier example class Shape is an abstract class, and objects can not be created from t...