设为首页 加入收藏

TOP

引用的本质分析(一)
2019-09-15 00:32:29 】 浏览:85
Tags:引用 本质 分析

1. 引用的定义

C++新增加了引用的概念:

  • 引用可以看作一个已定义变量的别名
  • 引用的语法Type &name = var;
int a = 4;
int &b = a;  //b为a的别名
b = 5;       //操作b就是操作a

2. 引用的本质

  • 引用在C++中的内部实现是一个常量指针Type &name <==> Type *const name
  • C++编译器在编译过程中使用常量指针作为引用的内部实现,因此引用所占用的内存大小和指针相同
  • 从使用的角度,引用只是一个别名,C++为了实用性而隐藏了引用的存储空间这一细节
#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 &)的大小,就是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. 引用的意义

  • C++中的引用作为变量别名而存在,旨在大多数的情况下代替指针
  • 引用可以满足绝大多数需要使用指针的场合
  • 引用可以避开由于指针操作不当而带来的内存错误
  • 引用相对于指针来说具有更好的可读性和实用性

注意:由于引用的内部实现为指针,因此函数不能返回非静态局部变量的引用

#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. 特殊的引用—const引用

  • 在C++中可以声明const引用const Type &name = var
  • 可以使用const常量、变量、字面值常量对const引用初始化
  • 不管使用何种方式初始化,const引用都将产生一个只读变量
  • 当使用字面值常量对const引用初始化时,C++编译器会为常量值分配内存空间,并将引用作为这段内存空间的别名

const引用类型 VS 初始化变量类型

  • 类型相同,const引用的就是初始化变量
  • 类型不同,const引用的不是初始化变量,而是初始化变量的临时对象

注意:const只是修饰符,不代表类型,也就是说,const int和int是相同类型。

#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的类型和rb相同,rb引用的就是b,所以改变rb的值,b也跟着一起改变
    printf("c = %c\n", c);  //c的类型和rc不同,rb引用的是c的临时对象,所以改变rc的值,c不受影响

    return 0;
}

5. 引用和指针的关系

指针 引用
指针是一个变量,其值为一个内存地址 引用是一个变量的新名字
指针可以不初始化,而是在使用时赋值 引用必须在定义时初始化
通过指针可以访问对应内存地址中的值 对引用
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇内联函数分析 下一篇关于c++模板非类型参数中指针和引..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目