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.
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.
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.
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
Constant Objects- write a constructor for that class
- in the constructor, initialize the const member using member initializer list
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
Post a Comment