• 第5课.引用的本质分析


    1.引用的意义

    a.作为变量别名而存在,在一些场合代替指针
    b.相对于指针来说具有更好的可读性和实用性

    注:函数中的引用形参不需要进行初始化
    使用指针

    使用引用

    2.特殊的引用

    a.在c++中可以声明const引用
    const Type& name = var; //这里使a为只读变量
    const 引用让变量拥有只读属性(只可间接的去修改)

    b.当使用常量对const引用进行初始化时,常量分配空间,并将引用名作为这段空间的别名(不使用consr不能使用常量对引用初始化)

        const  int& b = 1;        //分配一个空间,空间名为b,其中值为1
        int *p = (int *) &b;
        b = 5;             //对只读变量赋值,error    
        *p = 5;            //间接赋值
    

    eg:

        #include <stdio.h>
        void Example()
        {
            printf("Example:
    ");
    
            int a = 4;
            const int& b = a;
            int* p = (int*)&b;
    
            //b = 5;           //错误语句
    
            *p = 5;
    
            printf("a = %d
    ", a);
            printf("b = %d
    ", b);
        }
    
        void Demo()
        {
            printf("Demo:
    ");
    
            const int& c = 1;
            int* p = (int*)&c;
    
            //c = 5;            //    错误
    
            *p = 5;
    
            printf("c = %d
    ", c);
        }
    
        int main(int argc, char *argv[])
        {
            Example();
    
            printf("
    ");
    
            Demo();
    
            return 0;
        }
    

    思考:引用有他自己的存储空间吗?
    引用在c++中的内部实现就是一个指针常量(Type *const name)

    注意:
    a.c++编译器在编译过程中使用指针常量作为引用的内部实现,所以引用所占空间大小与指针相同(4byte)
    b.从使用的角度,引用只是一个别名,c++为了实用性隐藏了引用的存储空间这一细节

    #include <stdio.h>
    
    int& demo()
    {
    	int d = 0;
    	
    	printf("demo: d = %d
    ", d);
    	
    	return d;             //返回引用(int&)即返回(int *const),也就是需要返回d的地址。
                                          //返回地址后,这段数据在这个函数结束后就被,释放了。有问题
    }
    
    int& func()
    {
    	static int s = 0;            //static 决定返回的数据不会被释放掉,所以下面返回时不会有问题
    	
    	printf("func: s = %d
    ", s);
    	
    	return s;
    }
    
    int main(int argc, char* argv[])
    {
    	int& rd = demo();            //int& rd = d;
    	int& rs = func();              //int& rs = s;
    	
    	printf("
    ");
    	printf("main: rd = %d
    ", rd);        //???
    	printf("main: rs = %d
    ", rs);        //0
    	printf("
    ");
    	
    	rd = 10;
    	rs = 11;
    	
    	demo();        //0
    	func();          //11
    	
    	printf("
    ");
    	printf("main: rd = %d
    ", rd);        //???
    	printf("main: rs = %d
    ", rs);        //11
    	printf("
    ");
    	
    	return 0;
    }
    

  • 相关阅读:
    扯蛋的密码规则
    【转】mysql安全基线设置
    阿里云安全基线 记录如下 不定时更新
    解决Apache的错误日志巨大的问题以及关闭Apache web日志记录
    cms如何绑定二级域名
    宝塔面板定时/同步备份网站及数据库至FTP存储空间完整教程
    宝塔部署项目报Warning: require(): open_basedir restriction in effect的解决方案
    git学习笔记(一)—— git环境搭建
    vim学习笔记(一)—— vim安装方法
    Intel Edison学习笔记(二)—— 入门环境配置
  • 原文地址:https://www.cnblogs.com/huangdengtao/p/11776855.html
Copyright © 2020-2023  润新知