[c/c + + selected topics] 03 Const keyword

preface

Differences between const c language and c + +

Serial numberconst in C languageconst in C + +
1const modified quantities are called constants, not constants. The absolute constants are the immediate numbers 10, 20, etcconst modifier is a constant
2const int a; It is not necessary to initialize, but it is impossible to give a legal valueconst modifier must be initialized
3const int a=10; int array[a]={0};a is also not allowed as a subscriptconst int a=10; int array[a]={0}, a can be used as a subscript

The following program can explain that const in c is a constant variable and const in c + + is a constant. When the value defined by const is used, it will be replaced by the initial value.

#include "stdio.h"


int main()//This is a cpp file
{
	const int a = 10;
	int *p =(int *) &a;
	*p = 30;
	printf("%d %d  %d\n", a, *p, *(&a));//30 in C; In C + +, it is 10 30 10

}

Let's change the above program to the following, then the print in c + + is the same as that in c, because a here becomes a constant variable, not a constant.

#include "stdio.h"


int main()//This is a cpp file
{
	int b = 20;
	const int a = b;
	int *p =(int *) &a;
	*p = 30;
	printf("%d %d  %d\n", a, *p, *(&a));//30 in C; 30 in C + +

}

The following introduction is const in c + +

Const is the abbreviation of constant. Its original meaning is unchanged and difficult to change. In C + +, it is used to modify built-in type variables, custom objects, member functions, return values and function parameters. The usage of const is very flexible. Using const can improve the robustness of the program. The amount modified by const is called a constant. What is the difference between const and ordinary variables? It mainly includes two points: 1 Different compilation methods. 2. Cannot be used as an lvalue.

1. Modify common type variables

Const modifies a variable of ordinary Type. There are two forms, which are essentially the same. The Type of const modifier is immutable to the Type variable, and the const variable must be initialized.

1.Type const VarName = value;
2.const Type VarName = value;

In example 1, a is defined as a constant, and a can be assigned to b, but a cannot be assigned again. It is illegal to assign a value to a constant because a is considered a constant by the compiler and its value cannot be modified.

const int  a = 7; 
int  b = a; // correct
a = 8;       // Error, cannot be changed

Example 2: for const variable a, we take the address of the variable and assign it to the pointer pointing to int, and then use * p = 8; Reassign the value in the address of variable a, and then output the value of view a. From the debug window below, you can see that the value of a is changed to 8, but the output is still 7. This is because where a is used, the compiler will directly replace it with the initial value.

#include<iostream>
 
using namespace std;
 
int main(void)
{
    const int  a = 7;
    int  *p = (int*)&a;
    *p = 8;
    cout<<a;   // The print result is 7
    system("pause");
    return 0;
}


If we want to change the value of a above, we can use the Volatile keyword, for example:

#include<iostream>
 
using namespace std;
 
int main(void)
{
    volatile const int  a = 7;
    int  *p = (int*)&a;
    *p = 8;
    cout<<a;  // The print result is 8
    system("pause");
    return 0;
}

You can also add extend in front of const to change const to an external connection. Its function is to expand to the global. Memory will be allocated during compilation, and it can be used only as a declaration. The compiler thinks it has been defined elsewhere in the program.

extend const int VarName = value;

2. Modify pointer variables

Common errors in const modifier amount:

  1. A constant cannot be an lvalue because it directly modifies the value of the constant.
  2. You can't disclose the address of a constant to an ordinary pointer or ordinary reference variable, because you can modify the value of the constant indirectly.
#include "stdio.h"

int main()
{
	const int a = 10;
	a = 20;   // error
	int *p = &a;  // Error int * < = const int*

}

Combination of const and first level pointer

Description: c + + language specification, const modifies the nearest type.

There are four combinations:

  1. const int *p = 8; const modifies the content pointed to by the pointer, then the content is non variable.
  2. int const * p; The closest to const are * and int, where * cannot be used as a type, so the closest type to const is int, so it is the same as the first.
  3. Const modifies the pointer, then the pointer is non variable. int * const p ;
  4. Const modifies the pointer and the content pointed to by the pointer, then both the pointer and the content pointed to by the pointer are immutable. const int * const p

For the first and second: the content 8 pointed to by the pointer cannot be changed.

const int *p = 8;
*p = 9; // error

For the third: const pointer p, the memory address it points to cannot be changed, but its content can be changed.

int a = 8;
int* const p = &a;
*p = 9; // correct
int  b = 7;
p = &b; // error

For the fourth type: the content and memory address pointed to by const p are fixed and cannot be changed.

int a = 8;
const int * const  p = &a;

Combination of const and secondary pointer

There are three ways to combine:

  1. const int ** q **q cannot be assigned
  2. int * const * q *q cannot be assigned
  3. Int * * const Q cannot be assigned

3. Type conversion

const and pointer type conversion

transformationIs it correct
int * <= const int *error
cosnt int * <= int *correct
int ** <= const int **error
const int ** <= int **error
int ** <= int * const *error
int * const * <= int **correct
int ** const <= const int **error
const int ** <= int ** consterror

The address of a constant cannot be disclosed to an ordinary pointer or ordinary reference variable.

Const if there is no pointer * on the right, const does not participate in the type, as shown in the following code,

	int *p1 = nullptr;
	int * const p2 = nullptr;
	cout << typeid(p1).name << endl;   // int *
	cout << typeid(p1).name << endl;   // Int * Don't think it's int * const here

4. Reference

What is the difference between a reference and a pointer?

  • A safer pointer when referencing
  • References must be initialized, and pointers may not be initialized
  • The reference has only one level, and the pointer has one level and multiple levels
  • The assembly instructions of defining a reference variable and defining a pointer variable are the same. Modifying the value of the referenced memory through reference and modifying the value of the pointer pointing to memory through pointer dereference are the same.
	int array[5] = { };
	int (&p) [5] = array;
	int * q = array;

	cout << sizeof(array) << endl;  // 20  
	cout << sizeof(p) << endl;      // 20
	cout << sizeof(q) << endl;      //4

Lvalue reference and rvalue reference

**Lvalue: * * it has memory and name. The value can be modified, such as int a = 10;

**Right value: * * no memory, no name. For example: 20, not 20 = 10;

c++11 right value reference: int & & C = 20; It is specially used to refer to the right value type. On the instruction, it can automatically generate temporary quantities.

An R-value reference variable is itself an l-value, because it has a name and memory, as can be seen as follows:

	int && c = 20;
	int &b = c;

An R-value reference needs to reference an R-value, and an l-value cannot be referenced

	int a = 20;
	int && e = a;  // error
	int && e = 20;  //correct

3. Used in function

const can be used in function parameters in three cases:

1. Const modification is used in value transfer. Generally, const modification is not required because the function will automatically generate temporary variables to copy the argument values

#include<iostream>
 
using namespace std;
 
void Cpf(const int a)
{
    cout<<a;
    // ++a;   Is wrong, a cannot be changed
}
 
int main(void)
 
{
    Cpf(8);
    system("pause");
    return 0;
}

2. When const parameter is a pointer, the pointer can be prevented from being tampered with accidentally.

#include<iostream>
 
using namespace std;
 
void Cpf(int *const a)
{
    cout<<*a<<" ";
    *a = 9;
}
 
int main(void)
{
    int a = 8;
    Cpf(&a);
    cout<<a; // a is 9
    system("pause");
    return 0;
}

3. The parameter transfer of user-defined types requires the temporary object to copy the parameters. For the construction of temporary objects, the constructor needs to be called, which is a waste of time. Therefore, we adopt the method of const plus reference transfer. And for general built-in types such as int and double, we do not use the transfer method of reference. (why)

#include<iostream>
 
using namespace std;
 
class Test
{
public:
    Test(){}
    Test(int _m):_cm(_m){}
    int get_cm()const
    {
       return _cm;
    }
 
private:
    int _cm;
};
 
 
 
void Cmf(const Test& _tt)
{
    cout<<_tt.get_cm();
}
 
int main(void)
{
    Test t(8);
    Cmf(t);
    system("pause");
    return 0;
}

For the return value of const modifier function

1.const modifies the return value of a built-in type. Modifying the return value is the same as not modifying the return value.

#include<iostream>
 
using namespace std;
 
const int Cmf()
{
    return 1;
}
 
int Cpf()
{
    return 0;
}
 
int main(void)
{
    int _m = Cmf();
    int _n = Cpf();
 
    cout<<_m<<" "<<_n;
    system("pause");
    return 0;
}

2.const modifies the value of a user-defined type as the return value. At this time, the returned value cannot be used as an lvalue, and cannot be assigned or modified.

3.const modifies the returned pointer or reference. Whether to return a pointer to const depends on what we want the user to do. todo example

4. Modify class member function

Const modifies class member functions to prevent member functions from modifying the value of the called object. If we don't want to modify the value of a calling object, all member functions should be declared const member functions.

**Note: * * const keyword cannot be used together with static keyword, because static keyword modifies static member function. Static member function does not contain this pointer, that is, it cannot be instantiated. Const member function must be specific to an instance.

Get below_ cm()const; Function uses const member function:

#include<iostream>
 
using namespace std;
 
class Test
{
public:
    Test(){}
    Test(int _m):_cm(_m){}
    int get_cm()const
    {
       return _cm;
    }
 
private:
    int _cm;
};
 
 
 
void Cmf(const Test& _tt)
{
    cout<<_tt.get_cm();
}
 
int main(void)
{
    Test t(8);
    Cmf(t);
    system("pause");
    return 0;
}

If get_cm() removes the const modifier, then the const passed by Cmf_ TT even if the value of the object is not changed, the compiler thinks that the function will change the value of the object, so we try to treat all functions that do not need to change the content of the object as const member functions as required.

What if a member function wants to modify a member in an object? At this time, we can use the mutable keyword to modify this member. The meaning of mutable is also changeable and easy to change. The members modified by the mutable keyword can be in constant change, as shown in the following example.

#include<iostream>
using namespace std;
class Test
{
public:
    Test(int _m,int _t):_cm(_m),_ct(_t){}
    void Kf()const
    {
        ++_cm; // error
        ++_ct; // correct
    }
private:
    int _cm;
    mutable int _ct;
};
 
int main(void)
{
    Test t(8,7);
    return 0;
}

Here we pass in Kf()const++_ ct; Modification_ The value of CT, but through++_ cm modification_ cm will report an error. Because++_ cm is not decorated with mutable.

Welcome to my official account, "Liu Wang". The original technical article is pushed for the first time.

Keywords: C++ const

Added by owned on Sun, 23 Jan 2022 17:24:13 +0200