Beruflich Dokumente
Kultur Dokumente
Pi19404
November 23, 2013
Contents
Contents
C++ Const,Volatile Type Qualiers
0.1 Introduction . . . . . . . . . . . . . 0.2 Type Qualifiers . . . . . . . . . . . 0.2.1 Const Type Qualifiers Volatile Type Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 3 3 11
2 | 11
3 | 11
In case of class object,all the member variables must be initialized in the constructor A default user defined constructor will initialize all the values to random value.
class X{ X(){}; void print(){}; int a; } int main() { const X obj; const int f=1; }
When object is defined as constant,no data members of class can be modified,or any non-constant member function cannot be called. You cannot use const data objects in expressions requiring a modifiable lvalue,ie left side of assignment
class X{ X(){}; void print(){}; int a; } int main() { const X obj; const int f=1; f=2; obj.a=2; obj.print(); }
4 | 11
void foo(int j) { const int k = j; int ary[k]; /* Violates rule that the length of each array must be known to the C compiler, however this is allowed in C++ compiler */ }
A const variable has internal linkage by default,storage qualifiers need to be specified explicitly. Const Objects can be used in header files,since they have internal linkages and can be used instead of #define for constant values; For a const pointer, you must put the keyword between the * and the identifier In this case the the value of pointer/address cannot be changed but the value the pointer is pointing to can be changed.
int c=0; int * const y=&c; int a=10,b=20; *y=a; cout << *y << ":" << y << endl; *y=b; cout << *y << ":" << y << endl;
int c=0; int * const y=&c; int a=10,b=20; y=&a; //this line will give compilation error
5 | 11
To define a pointer to a const value,the keyword must be placed before the type specifier.
int c=0; const int * y=&c; int a=10,b=20; y=&a; cout << *y << ":" y=&b; cout << *y << ":" a=30; cout << *y << ":"
// A pointer to a constant integer << &c <<":" << y << endl; << &c <<":" << y << endl; << &c <<":" << y << endl;
We can change the values of a,b,c and since in the last line pointer points to address of b,we can deference the pointer and obtain the value of new variable.
we can see that the pointer can be changed,however changing the value the pointer y points gives a error.It is a pointer to a const integer Any expression of the form y = 1 will give an error.We cannot change the value of the variable via pointer.
int c=0; const int * y=&c; // A pointer to a constant integer *y=1; //this line gives error
In the below expression neither the value pointed to or the pointer can be changed
6 | 11
class X{ int x; public: X():x(100){}; void print() const{ x=1; //this gives error } };
class X{ int x; public: X():x(100),a2(200){a1=&x;}; void print2 (){ } void print() const{ print2();//this gives error } }; int main() { X obj; obj.print(); }
If a object of class is delared as const,it can only call const functions of the class,but not non-const functions of the class.Delaring the object as const means that this pointer is a pointer to a const object.
class X{ int x; public: X():x(100){}; void print2 (){ } void print() const{ }
7 | 11
}; int main() { const X obj; obj.print(); //this does not give error obj.print2(); //this gives an error }
If a function is defined as const we can still change the value using const_cast A better approach would be to declare the variable desired to be changed as mutable.
class X{ int x; public: X():x(100){}; void print() const{ const_cast <int &> (x)=1; // will not give error } };
The mutable storage class specifier is used only on a class data member to make it modifiable even though the member is part of an object declared as const or function is declared as const.
class X{ mutable int x; public: X():x(100){}; void print() const{ x=1; //this is allowed since x is mutable } int main() { const X obj; obj.print(); } };
- Pointer to constant data can be used as function parameters to prevent the function from modifying a parameter passed through a pointer or passed as a reference.
8 | 11
class X{ public: X(){} void print(const int * x2,const int & x1) { *x2=1; //poiner to const data,hence will give error x1=1; //reference to const data,hence will give erro } };
The member function can also return a const value or reference to const value. A return of a object invokes a copy constructor while returning a reference does not invoke a copy constructor.Thus for efficiency it can be used.However the return by reference supplies the local address of a variable,not if the main object has been deallocated,the value which address points to is undefined. The reference should be to an object that exists.
class X{ public: X(){} const int &print(const int * x2,const int & x1) { int x3=1; cerr << x3 <<":" << &x3 << endl; return x3; } }; int main() { X *obj=new X(); int x=0; const int & x4=obj->print(&x,x); cerr << x4 <<":" << &x4 << endl; delete obj; cerr << x4 <<":" << &x4 << endl; }
9 | 11
we can see that value pointed by x4 is difference after the object has been deallocated. This is inherent drawback of call be reference,where user must ensure that the object is not being referenced.
however in case of applications like streaming camera frames,sensor data etc we do not want to allocate a new address for every new frame of data . In this case returning a constant reference or pointer provides a effcient way of providing the data without copying it or allocating it everytime.
class X{ int x3; public: X():x3(0){} const int &get() { x3=x3+1; return x3; } }; int main() { X *obj=new X(); int x=0; for(int i=0;i<2;i++) { const int & x4=obj->get(); cerr << x4 <<":" << &x4 << endl; //address of x4 is same as x3 } }
10 | 11
11 | 11