Essential Analysis of Citation

Catalog

1. Definition of reference

C++ adds the concept of reference:

  • A reference can be seen as an alias for a defined variable
  • The reference grammar Type & name = var;
int a = 4;
int &b = a;  //b is an alias for a
b = 5;       //Operation b is operation a

2. Essence of Citation

  • The internal implementation referenced in C++ is a constant pointer Type & name <=> Type * const name
  • C++ compilers use constant pointers as internal implementations of references during compilation, so references occupy the same memory size and pointers.
  • From the point of view of usage, reference is only an individual name, and C++ hides the details of reference storage space for practicality.
#include <cstdio>

struct TRef
{
    char &r;
};

int main(int argc, char *argv[])
{
    char c = 'c';
    char &rc = c;
    TRef ref = { c };

    printf("sizeof(rc) = %d\n", sizeof(rc));
    printf("sizeof(TRef) = %d\n", sizeof(TRef)); 
    printf("sizeof(ref) = %d\n", sizeof(ref)); 
    printf("sizeof(ref.r) = %d\n", sizeof(ref.r));   

    /*sizeof(type &)Size is the size of type type*/ 
    printf("sizeof(char &) = %d\n", sizeof(char &));  
    printf("sizeof(int &) = %d\n", sizeof(int &));
    printf("sizeof(double &) = %d\n", sizeof(double &));

    return 0;
}

#include <stdio.h>

struct TRef
{
    char *before;
    char &ref;
    char *after;
};

int main(int argc, char *argv[])
{
    char a = 'a';
    char &b = a;
    char c = 'c';

    TRef r = {&a, b, &c};

    printf("sizeof(r) = %d\n", sizeof(r));
    printf("sizeof(r.before) = %d\n", sizeof(r.before));
    printf("sizeof(r.after) = %d\n", sizeof(r.after));
    printf("&r.before = %p\n", &r.before);
    printf("&r.after = %p\n", &r.after);

    return 0;
}

3. Significance of Citation

  • References in C++ exist as variable aliases to replace pointers in most cases
  • References can satisfy most situations where pointers are needed
  • References can avoid memory errors caused by improper pointer manipulation
  • Reference has better readability and practicability than pointer

Note: Because the internal implementation of the reference is a pointer, the function cannot return references to non-static local variables.

#include <stdio.h>

int &demo()
{
    int d = 0;

    printf("demo: d = %d\n", d);

    return d;
}

int &func()
{
    static int s = 0;

    printf("func: s = %d\n", s);

    return s;
}

int main(int argc, char *argv[])
{
    int &rd = demo();
    int &rs = func();

    printf("\n");
    printf("main: rd = %d\n", rd);
    printf("main: rs = %d\n", rs);
    printf("\n");

    rd = 10;
    rs = 11;

    demo();
    func();

    printf("\n");
    printf("main: rd = %d\n", rd);
    printf("main: rs = %d\n", rs);
    printf("\n");

    return 0;
}

4. Special Reference - const Reference

  • In C++ you can declare that const refers to const Type & name = var
  • Const references can be initialized using const constants, variables, literal value constants
  • Regardless of how initialized, a const reference produces a read-only variable
  • When a literal constant is used to initialize a const reference, the C++ compiler allocates memory space for the constant and uses the reference as an alias for that memory space.

const Reference Type VS Initialization Variable Type

  • With the same type, const refers to initialization variables
  • Different types, const refers not to initialization variables, but to temporary objects that initialize variables.

Note: Const is just a modifier, not a type, that is to say, const int and int are the same type.

#include <stdio.h>

int main()
{
    const int a = 3;
    int b = 4;
    char c = 'c';

    const int &ra = a;
    const int &rb = b;
    const int &rc = c;
    const int &rd = 1;

    int *p1 = (int *)&ra;
    int *p2 = (int *)&rb;
    int *p3 = (int *)&rc;
    int *p4 = (int *)&rd;

    *p1 = 5;
    *p2 = 6;
    *p3 = 7;
    *p4 = 8;

    printf("ra = %d\n", ra);
    printf("rb = %d\n", rb);
    printf("rc = %d\n", rc);
    printf("rd = %d\n", rd);

    printf("\n");

    printf("b = %d\n", b);  //B is the same type as rb, RB refers to b, so change the value of rb, B also changes with it.
    printf("c = %c\n", c);  //The type of C is different from that of rc. rb refers to the temporary object of c, so changing the value of RC does not affect C.

    return 0;
}

5. The relationship between reference and pointer

Pointer Quote
A pointer is a variable whose value is a memory address Reference is a new name for a variable
Pointers can be assigned when they are used instead of being initialized. References must be initialized at definition time
The value in the corresponding memory address can be accessed by a pointer Operations on references (assignments, addresses, etc.) are passed on to the variables represented.
Pointer can save different addresses References cannot represent other variables after initialization
A pointer can be modified by const to be a constant or read-only variable. const references make the variables it represents read-only

In the Development of Engineering Projects

  • When programming in C++ language, directly from the point of view of use, reference and pointer have nothing to do with each other.
  • When debugging and analyzing C++ code, some special cases can be considered, from the point of view of C++ compiler, to refer to internal implementation as pointer constant.

Let's give an example of looking at references from the perspective of a C++ compiler. Is there a problem with the following code?

int a = 1;
int b = 2;
int *pc = new int(3);
int &array[] = {a, b, *pc};
  • An array is a continuous piece of memory space.
  • Reference arrays can break this feature, and variables represented by each element may be stored in different locations.
  • Therefore, C++ does not support reference arrays!!!!!!
#include <stdio.h>

int a = 1;

struct SV
{
    int &x;
    int &y;
    int &z;
};

int main()
{
    int b = 2;
    int *c = new int(3);
    SV sv = {a, b, *c};
    int &array[] = {a, b, *c}; //& array [1] - & array [0]!= 4, compilation error

    printf("&sv.x = %p\n", &sv.x);
    printf("&sv.y = %p\n", &sv.y);
    printf("&sv.z = %p\n", &sv.z);

    delete c;

    return 0;
}

First, comment out line 17 of the code. The results of the compilation run are as follows. It can be seen that the printed memory addresses are different.

Then, the comment on line 17 of the code is removed, resulting in compilation errors because the addresses of the three elements of the array are not continuous, but different.

Keywords: C++ P4 Programming

Added by dzm on Sat, 14 Sep 2019 16:48:41 +0300