zoukankan      html  css  js  c++  java
  • c++------引用(左值与右值,引用一个数组,const限制)

    &与&&
      对于在C++中,大家对于符号“ & ”的第一映像是引用和取地址,对符号“ && ”的第一映像是逻辑与。但是在C++11中我们会看到下方这种表示方法:

    int &&k=i+k;
    1
      对于第一眼见到上述的表达方式时,估计会一脸懵逼。下面对此做一个简述。
      引用 & 是一个类型变量的别名。
      通常使用 “ & ”是作为普通的左值引用,左值是可以放在赋值号 “ = ”的左边的值。
      &&是右值引用,右值是只能放在 “ = ” 右边的值,右值没有一个 “ 变量 ”名字。如:

    int && k =i+j;
    1
      i+j 返回的值可以视做是放在一个临时存放内存空间里的,这个空间并不能用来赋值,你不能些i+j=5等; && 可以把这种临时的值和存在变量里的值区分开来。
      右值短暂,右值只能绑定到临时对象。所引用的对象将要销毁或对象没有其他用户。
      初始化时右值引用一定要用一个右值表达式绑定,初始化之后,可以用左值表达式或修改右值引用的所引用临时对象的值。
      右值引用是对临时对象的一种引用,它是在初始化时完成引用的,但是右值引用不代表引用临时对象后,就不能改变右值引用所引用对象的值。仍然可以在初始化后改变临时对象的值。

      对于引用类型,可以用于它所引用对象类型的可以用的地方(把他当成普通变量),只不过用到的值是它所引用的对象的值,还可以用于移动构造和赋值函数的地方。

    例子

    #include <algorithm>
    #include <iostream>
    #include <functional>
    #include <vector>
    #include <numeric>
    #include <array>
    #include <cstring>
    #include <cstdio>
    #include <windows.h>
    using namespace  std;
    //c++能用引用的情况就不要用指针
    
    
    int main1()
    {    
        int num = 10;//num左值,内存实体
        int& rnum(num);//变量的别名
        rnum = 1;//rnuum等价于num的别名
        cout << num << endl;//1
        system("pause");
    }
    ////右值引用 ,节约内存,快速引用寄存器的值
    int main()
    {
        int num = 1;
        int &&rnum(num + 4);//右值引用,快速备份,编译器自动回收
        printf("%p",&rnum);
        int data = num+4;
        int &rdata(data);//左值引用
        cout << (void*)&data << endl;
        
        data=num+1;
    }
    void main()
    {
        int a[5] = { 1, 2, 3, 4, 5 };
        int *p(a);
        //cout << *p << endl;//1
        //int* &rp(p);//左值引用改变指针
        //rp += 1;
        //cout << *p << endl;//2
        int *&&rrp(p+2);//右值引用&&
        cout << *rrp << endl;//3
        rrp += 2;
        cout << *rrp << endl;//5
    
    }
    void showit(int&& rrnum)
    {
        cout << rrnum << endl;
    }
    //左值应用往往引用的是内存里面的值,而右值引用一般是寄存器里面的值
    void  main()
    {
        int a[5] = { 1, 2, 3, 4, 5 };
        showit(a[3] + 2);//5,右值引用大大节约内存
        showit(move(a[3]));//move移动语义,左值变长右值
    }
    

      

    引用的本质:
    
    #include <algorithm>
    #include <iostream>
    #include <functional>
    #include <vector>
    #include <numeric>
    #include <array>
    #include <cstring>
    #include <cstdio>
    #include <windows.h>
    using namespace  std;
    void  main1()
    {
        int num = 10;
        int data = 20;
        int & rnum(num);//引用一旦初始化,不会再引用其他的变量
        rnum = data;
        cout << num << endl;//20
        cout << data << endl;20
    }
    void main()
    {
        double db;
        double&rdb(db);
        cout << sizeof(rdb) << endl;//8,编译器优化处理,引用变量名的别名
        struct Mystruct //引用的本质是指针实现的,用于简化程序
        {
            double &rdb;
        };
        cout << sizeof(Mystruct) << endl;//4
    }
    
    

     

    引用作为参数
    
    #include <algorithm>
    #include <iostream>
    #include <functional>
    #include <vector>
    #include <numeric>
    #include <array>
    #include <cstring>
    #include <cstdio>
    #include <windows.h>
    using namespace  std;
    //改变指针需要二级指针
    //栈区,自动回收,释放,返回值为指针,不能指向栈区,返回引用,不能引用栈区
    
    int main()
    {
        int a(4);//初始化为4
        int*p(new int(5));//初始化为5
        cout << a << endl;//4
        cout << *p << endl;//5
        int &ra(a);//引用变量
        int*&rp(p);//引用指针
    
        ra = 3;
        *rp = 12;
    
        cout << a << endl;//3
        cout << *p << endl;//12
    
    
        cin.get();
    }
    int main()
    {
        int a(4);//初始化为4
        int*p(new int(5));//初始化为5
        cout << a << endl;//4
        cout << *p << endl;//5
    
        int&&rra(move((a)));//右值,有内存实体,就直接引用,没有就开辟内存
        int *&&rrp(move(p));
        rra = 1;
        cout << rra <<endl;//1
        cout << a << endl;//1
        
        //int&:引用内存实体,引用整数,本质是指针
        //int&&:引用整数,本质是指针,能处理左值和右值,处理左值需要配合move
        //int:整数类型
        cin.get();
    }
    int num1 = 10;
    int num2 = 20;
    void change(int *&rp)
    {
        rp = &num2;
    }
    void main()//c++能用引用就别用指针 
    {
        int *p = #
        change(p);
        cout << *p << endl;//20;
    }
    
    int main()
    {
        int *p(nullptr);
        int**pp = &p;
        int**&rpp = pp;//vs2015
        //vs2013中:int(**(&rpp))(pp);
        //vs2013:int(*(&rpf)),需考虑优先级
    }
    void main()
    {
        //vs2015
        int***ppp(nullptr);
        int***&rppp(ppp);
        //vs2013
        int(***ppp)(nullptr);
        int(***(&rppp))(ppp);
    }
    
    
    int data = 10;
    int data2 = 20;
    int *p = &data;
    void change(int **&rpp)//引用
    {
        *rpp = &data2;
    }
    int main()
    {
        int **pp = &p;//二级指针
        cout << **pp << endl;//10;
        change(pp);
        cout << **pp << endl;//20;
    }
    int& getdata()
    {
        int num = 10;//销毁了,调用结束自动销毁
        return num;
    }
    
    
    int main()
    {
        //int & rnum = getdata();//引用原来的内存,已经销毁的地方,乱码
        int & rnum = getdata();//拷贝到新的内存
        cout << "hello";
        cout << rnum << endl;
        printf("%d",getdata());//10
    }
    char*& getcode()
    {
        char*p = "hello world";//指向只读数据区
            return p;
    }
    void  main()
    {
        char*&rp = getcode();//引用本质是指针,引用的就是函数中的p,而那个内存可能已经释放
        char*newp = rp;//保存rp存储代码区的地址
        cout << "hello " << endl;
        cout << newp << endl;//输出hello world
        cout << rp << endl;//乱码;
    }
    

      

     

    引用一个数组及引用数组是非法的

    #include <algorithm>
    #include <iostream>
    #include <functional>
    #include <vector>
    #include <numeric>
    #include <array>
    #include <cstring>
    #include <cstdio>
    #include <windows.h>
    using namespace  std;
    int main()
    {
    	int a[5]{1, 2, 3, 4, 5};
    	int *pa[5] = { a, a + 1, a + 2, a + 3, a + 4 };
    	int b[3][4]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    	int*pb[3][4]{&b[0][0], &b[0][0] + 1, &b[0][0] + 2, &b[0][0]+3,........}
    	int *p1(new int[5]{1, 2, 3, 4, 5});//堆上的一维数组
    
    	int(*p2)[4](new int[3][4]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});//堆上的二维数值
    	cin.get();
    }
    
    void main()
    {
    	int a[5]{1, 2, 3, 4, 5};
    	//int a[5] == == > int(&ra)[5](a);//引用数组,用a初始化
    	int *pa[5] = { a, a + 1, a + 2, a + 3, a + 4 };
    	int(&ra)[5](a);//引用数值
    	int*(&rpa)[5](pa);//引用指针数值
    	for(auto& i:ra)
    	{
    		cout << i+=1 << endl;//会修改数据
    	
    	}
    	for (auto i:rpa)
    	{
    		cout << *i << endl;
    	}
    }
    void main()
    {
    // 	int *p1(new int[5]{1, 2, 3, 4, 5});//堆上的一维数组
    // 	int **pp ( new int*[5]{p1,p1+1,p1+2,p1+3,p1+4});//堆上的指针数组
    // 	int*&rp(p1);
    // 	int **&rpp(pp);//vs2015
    	//vs2013以下
    		int *p1(new int[5]{1, 2, 3, 4, 5});//堆上的一维数组
    		int *(*pp) ( new int*[5]{p1,p1+1,p1+2,p1+3,p1+4});//堆上的指针数组
    		int(*(&rp))(p1);
    	 	int (**(&rpp))(pp);
    	for (int i = 0; i < 5;i++)
    	{
    		cout << rp[i] << endl;
    	}
    	for (int i = 0; i < 5; i++)
    	{
    		cout << *rpp[i] << endl;
    	}
    }
    void main()
    {
    	int b[3][4]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    	int*pb[3][4]{&b[0][0], &b[0][0] + 1, &b[0][0] + 2, &b[0][0] + 3, ........}
    	int(&rb)[3][4](b);//引用二维数值
    	int *(&rpb)[3][4](pb);
    	for (int i=0;i<3;i++)
    	{
    		for (int j = 0; j < 4; j++)
    		{
    			cout << rb[i][j];
    		}
    	}
    	for (int i = 0;i < 3;i++)
    	{
    		for (int j = 0; j < 4; j++)
    		{
    			cout << *rpp[i][j];
    		}
    	}
    
    }
    void main()
    {
    	//指向数组的指针,{}包含
    	int(*p2)[4](new int[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } });//堆上的二维数值
    	int(*&rp)[4](p);
    
    	int*(*pp)[4](new int*[3][4]);//在堆上开辟二维指针数值
    	int*(*&rpp)[4](pp);//引用二维指针数组
    	for (int i = 0;i < 3;i++)
    	{
    		for (int j = 0; j < 4; j++)
    		{
    			cout << rp[i][j];
    		}
    	}
    
    }
     int main)
     {
    	 int a = 1;
    	 int &ra(a);
    	 int b = 2;
    	 int &rb(b);
    	 int c = 3;
    	 int &rc(c);
    	 int &myarr[3]{ra, rb, rc};//错误,引用数组非法,只能单独引用
     }
    

      加const的引用

    #include <algorithm>
    #include <iostream>
    #include <functional>
    #include <vector>
    #include <numeric>
    #include <array>
    #include <cstring>
    #include <cstdio>
    #include <windows.h>
    using namespace  std;
    void main1()
    {
        int num = 100;
        int const& rnum(num);//让别人引用,限定权限,只能读不能写
        //rnum =3//不允许对常量赋值
        cout << rnum << endl;
    }
    void main2()
    {
        int num = 100;
        //int & const rnum(num);// 使用了记时错误: 忽略引用上的限定符,const会被忽略
    }
    void main3()
    {
    
        int a[5] = { 1, 2, 3, 4, 5 };
        const int(&ra)[5](a);
        for (auto &i:ra)
        {
            //i+=1;//只能读,不能写
            cout << i << endl;//只能读,不能写
    
    
        }
        cin.get();
    }
    void main()
    {
        int *p(new int(5));
        //int *&rp(p);
         int (*(&rp))(p);//
        *rp = 3;
        cout << *p << endl;//3
    }
    void main()
    {
    
        const int *const p(new int(4));
        *p = 1;
        const int*(*const(&rp))(p);//引用一个常量的常量指针
    }
    void show( const int& p)//明确只读
    void main()
    {
        int *p(new int(4));
        const int *&rp((const int *&)p);//强转成const int *的引用
    
    }
  • 相关阅读:
    有关css的效果展示
    php将代码上传至服务器步骤
    php连接数据库
    PHP如何从一个页面跳转到另一个页面
    Windows计算器
    查询本地正在运行的端口号
    wamp虚拟路径访问配置
    sublime text3 Emmet (原zenCoding)安装方法
    Latex(一)公式自动编号与自动引用
    Linux下Django开发学习(一)
  • 原文地址:https://www.cnblogs.com/bwbfight/p/11304231.html
Copyright © 2011-2022 走看看