Relationship between const and reference.

1. Special Use of References

1 Basic Review

int main()
{
    int a = 10;
    const int b = 20;
    
    //For integer a
    int &c1 = a;
 	const int &c2 = a;
    a = 2000;				//You can modify the value of c2 through a
    cout <<" a = "<< a << endl;
    cout <<" c1 = "<<c1 << endl;
    cout <<" c2 = "<<c2 << endl;
    
  
    
    //For integer constant b
    int &c3 = b;		//error, a constant variable can only be referenced frequently
    const int &c4 = b;
    
    return 0;
}

Run result:


Summary:

Ordinary variables can be referenced either normally or frequently.

Constant variables can only be referenced frequently.

2 Literal value constant

Define an alias that frequently refers to b as a and a alias that frequently refers to c as the literal constant 10. Defines an integer reference d as an alias for the literal constant 10.

int main()
{
    int a = 10;
    const int &b = a;
    //The above line of code corresponds to
    //const int *const b = &a;
    
    const int &c = 10;
    //The above line of code corresponds to
    //int tmp = 10;
    //const int &c = &tmp;
    //const int * const c = &tmp;
    
    int &d = 10;	//error
    
    return 0;
}

Summary: Literal constants are always referenced directly by common references, but literal constants cannot be referenced directly by ordinary references.

Question: Think about whether the bottom two ways are the same?

Answer: Not the same

    const int a = 10;
    const int &b = a;
    //The above two lines correspond to
    //const int a = 10;
    //const int *const b = &a;

    const int &c = 10;
    //The top row corresponds to
    //int temp = 10;
    //const int *cosnt c = &temp; 

VS2019 generates disassembly as follows:

    const int a = 10;
000D1832  mov         dword ptr [a],0Ah  
    const int& b = a;
000D1839  lea         eax,[a]  
000D183C  mov         dword ptr [b],eax  
    const int& c = 10;
000D183F  mov         dword ptr [ebp-30h],0Ah  
000D1846  lea         eax,[ebp-30h]  
000D1849  mov         dword ptr [c],eax  

Summary: From the above, it can be seen that there is a difference between referencing literal values and referencing ordinary variables.

A common reference to literal values requires that a temporary quantity be constructed to store the literal values.

3 Storage object array

Statically create an array of objects:

class Object
{
    int value;
public:
    Object(int x = 0) : value(x)    
    {
        cout << "create:" << this << endl;
    }
    void Print() const 
    {
        cout << value << endl;
    }
    ~Object()   
    {
        cout << "~Object:" << this <<endl;
    }
};

Object obj3(4);

int main()
{
    Object obj[10];
    return 0;
}

g++ Output Results:

create:0x407030
create:0x61fdd0
create:0x61fdd4
create:0x61fdd8
create:0x61fddc
create:0x61fde0
create:0x61fde4
create:0x61fde8
create:0x61fdec
create:0x61fdf0
create:0x61fdf4
~Object:0x61fdf4
~Object:0x61fdf0
~Object:0x61fdec
~Object:0x61fde8
~Object:0x61fde4
~Object:0x61fde0
~Object:0x61fddc
~Object:0x61fdd8
~Object:0x61fdd4
~Object:0x61fdd0
~Object:0x407030

Create object arrays dynamically using pointers:

int main()
{
    int n;
    cin >> n;	//variable
    Object *s = new Object(n);	//Only one object, call constructor
    Object *p = new Object[n];	//A set of objects
    
    //Don't forget to free up space
    delete[] p;					//Square brackets release a group of objects.
    delete s;
    return 0;
}

Question 1: What happens when you construct a set of objects without a default constructor?

Answer: Error

class Object
{
    int value;
public:
    Object(int x) : value(x)                //Delete default parameters
    {
        cout << "create:" << this << endl;
    }
    void Print() const 
    {
        cout << value << endl;
    }
    ~Object()   
    {
        cout << "~Object:" << this <<endl;
    }
};

Object obj3(4);

int main()
{
    int n;
    cin >> n;	//variable
    Object *s = new Object(n);	//Only one object, call constructor
    Object *p = new Object[n];	//A set of objects
    
    //Don't forget to free up space
    delete[] p;					//Square brackets release a group of objects.
    delete s;
    return 0;
}

Compile and run:

error: no matching function for call to 'Object::Object()'

No constructor found

Question 2: Can you use this with Object *p = new Object[n] (23)? This means that each object has 23 to initialize.

Answer: Error

class Object
{
    int value;
public:
    Object(int x) : value(x)                //Delete default parameters
    {
        cout << "create:" << this << endl;
    }
    void Print() const 
    {
        cout << value << endl;
    }
    ~Object()   
    {
        cout << "~Object:" << this <<endl;
    }
};

Object obj3(4);

int main()
{
    int n;
    cin >> n;	//variable
    Object *s = new Object(n);	//Only one object, call constructor
    Object *p = new Object[n](23);	//A set of objects that you want to initialize with 23
    
    //Don't forget to free up space
    delete[] p;					//Square brackets release a group of objects.
    delete s;
    return 0;
}

Compile:

error: parenthesized initializer in array new Object *p = new Object n;

The object takes new when the array is initialized.

Note: When writing a type, you must create a default constructor or you cannot create a set of objects.

Summary:

You can create a set of objects with new, but don't forget to free up the object space at the end.

When writing a type, you must create a default constructor, or you cannot create a set of objects.

Another use of 4 new

Next Update

Keywords: C++ Back-end

Added by DrTom on Wed, 19 Jan 2022 07:15:13 +0200