zoukankan      html  css  js  c++  java
  • 1.2引用

    C++的引用,水很深

    左值就是可以放在赋值号左边赋值的,必须要在内存有实体

    右值就是可以放在赋值号右边取出值赋给其他变量的值,可以在内存,也可以在CPU

    引用说明为对象建立引用名,即别名

    引用在定义初始化时与对象名绑定,程序中不能对引用重定义

    一个对象的别名,从使用方式和效果上,与使用对象名一致

    定义形式:类型&引用名=对象名;

    //引用可以改变指针的指向

    //引用可以改变指针指向的值

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int num1(5);
     7     int num2(10);
     8 
     9     int *pnum(&num1);
    10 
    11     int * & rpnum = pnum;//引用可以改变指针的指向
    12 
    13     *rpnum = 100;//引用可以改变指针指向的值
    14 
    15     rpnum = &num2;
    16 
    17     std::cout << *pnum << std::endl;//10
    18 
    19     system("pause");
    20 }

    //引用右值,一般用于企业开发,内存优化

    //用于对象拷贝

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int num1(5);
     7     int num2(10);
     8 
     9     int * && rpnum = &num1;//引用右值,一般用于企业开发,内存优化
    10 
    11     int *p = rpnum;//用于对象拷贝
    12 
    13     system("pause");
    14 }

    //指针与引用

    int a;

    int * pa;

    int & ra=a;

    pa=&a;

    改变外部变量,需要地址或者引用

    左值引用是用指针实现的

    返回引用的函数

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int & get()
     5 {
     6     int a = 10;//a在栈上
     7     int & ra = a;
     8 
     9     std::cout << "&a=" << &a << std::endl;
    10 
    11     return ra;
    12 }
    13 
    14 void main()
    15 {
    16     int & ra = get();
    17 
    18     std::cout << ra << std::endl;
    19 
    20     std::cout << "ABCD" << std::endl;
    21 
    22     std::cout << ra << std::endl;
    23     
    24     system("pause");
    25 }

    &左值引用

    &&右值引用

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int a = 10;
     7 
     8     int & ra = a;//&左值引用
     9 
    10     int * && pa = &a;//&&右值引用
    11 
    12     //int * & & pa1 = &a;//右值引用,不能分开写
    13     
    14     system("pause");
    15 }

    面试,函数指针

    int(*z(int x, int(*y)(int)))(int);

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int(*z(int x, int(*y)(int)))(int);
     7 
     8     //第一步,可以看成
     9     int(*T)(int);
    10 
    11     //z(int x, int(*y)(int))
    12     //z是一个函数,参数是一个整型变量和一个函数指针,返回值也是函数指针
    13 
    14     int(*y)(int);
    15     //参数也有一个函数指针
    16     
    17     system("pause");
    18 }

    函数指针数组

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int jia(int a, int b)//定义一个函数+
     5 {
     6     return a + b;
     7 }
     8 
     9 int jian(int a, int b)//定义一个函数-
    10 {
    11     return a - b;
    12 }
    13 
    14 void main()
    15 {
    16     int a = 10;
    17     int b = 2;
    18 
    19     int(*p[2])(int, int) = { jia,jian };//定义一个函数指针数组,并初始化
    20 
    21     std::cout << p[0](a, b) << " " << p[1](a, b) << std::endl;//12 8
    22 }

    参数是函数指针的引用,返回一个函数指针的引用

    int(*& z(int x, int(*& y)(int)))(int);

    int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

    int(&ra)[10](a);//引用一个一维数组

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
     7 
     8     //引用就是给变量有一个别名,同一个地址
     9 
    10     int(&ra)[10](a);//引用一个一维数组
    11 
    12     for (auto data : ra)//C++11遍历一维数组新方法
    13     {
    14         std::cout << data << std::endl;
    15     }
    16 
    17     std::cout << a << " " << ra << std::endl;
    18 
    19     std::cout << &a << " " << &ra << std::endl;
    20     
    21     system("pause");
    22 }

    int a[2][5] = { 1,2,3,4,5,6,7,8,9,10 };

    int(&ra)[2][5](a);//引用一个二维数组

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int a[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
     7 
     8     int(&ra)[2][5](a);//引用一个二维数组
     9 
    10     system("pause");
    11 }

    //创建一个函数指针,并初始化

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int jia(int a, int b)
     5 {
     6     return a + b;
     7 }
     8 
     9 void main()
    10 {
    11     int(*p)(int a, int b)(jia);//创建一个函数指针,并初始化
    12 
    13     std::cout << p(1, 2) << std::endl;//调用函数指针
    14 
    15     system("pause");
    16 }

    //引用一个函数指针

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int jia(int a, int b)
     5 {
     6     return a + b;
     7 }
     8 
     9 int jian(int a, int b)
    10 {
    11     return a - b;
    12 }
    13 
    14 void main()
    15 {
    16     int(*p)(int a, int b)(jia);//创建一个函数指针,并初始化
    17 
    18     int(*& rp)(int a, int b)(p);//引用一个函数指针
    19 
    20     std::cout << rp(1, 2) << std::endl;
    21 
    22     rp = jian;//引用重新赋值
    23 
    24     std::cout << rp(1, 2) << std::endl;
    25     
    26     system("pause");
    27 }

    //改变一个函数指针的指向,需要一个指向函数指针的指针,或者这个函数指针的引用

    void change(int(*& rp)(int, int))//参数值是函数指针的引用,无返回值

    {

    rp = jian;

    }

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int jia(int a, int b)
     5 {
     6     return a + b;
     7 }
     8 
     9 int jian(int a, int b)
    10 {
    11     return a - b;
    12 }
    13 
    14 //改变一个函数指针的指向,需要一个指向函数指针的指针,或者这个函数指针的引用
    15 
    16 void change(int(*& rp)(int, int))//参数值是函数指针的引用,无返回值
    17 {
    18     rp = jian;
    19 }
    20 
    21 void main()
    22 {
    23     int(*p)(int a, int b)(jia);//创建一个函数指针,并初始化
    24 
    25     change(p);//通过函数改变一个函数指针的指向
    26     
    27     system("pause");
    28 }

    //升级版,比旧版更好,有返回值,可以监测是否成功改变
    int(*& change(int(*& rp)(int, int)))(int, int)//参数值是函数指针的引用,返回一个函数指针的引用
    {
    rp = jian;
    return rp;
    }

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int jia(int a, int b)
     5 {
     6     return a + b;
     7 }
     8 
     9 int jian(int a, int b)
    10 {
    11     return a - b;
    12 }
    13 
    14 //旧版
    15 //void change(int(*& rp)(int, int))//参数值是引用一个函数指针,无返回值
    16 
    17 //第一步,引用函数指针
    18 //int(*& T)(int,int)
    19 
    20 //第二步,中间补上
    21 //升级版,比旧版更好,有返回值,可以监测是否成功改变
    22 int(*& change(int(*& rp)(int, int)))(int, int)//参数值是函数指针的引用,返回一个函数指针的引用
    23 {
    24     rp = jian;
    25     return rp;
    26 }
    27 
    28 void main()
    29 {
    30     int(*p)(int a, int b)(jia);//创建一个函数指针,并初始化
    31 
    32     std::cout << p(1, 2) << std::endl;
    33 
    34     p = change(p);//参数是函数指针的引用,返回一个函数指针的引用
    35 
    36     std::cout << p(1, 2) << std::endl;
    37     
    38     system("pause");
    39 }

    //error C2234: “p”: 引用数组是非法的

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int a = 1, b = 2, c = 3;
     7 
     8     int &p[4] = { &a,&b,&c };//error C2234: “p”: 引用数组是非法的
     9         
    10     system("pause");
    11 }

    //引用数组是非法的,可以用指针数组

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int a = 1, b = 2, c = 3;
     7 
     8     int *p[4] = { &a,&b,&c };//引用数组是非法的,可以用指针数组
     9         
    10     system("pause");
    11 }

    //函数在代码区,无论一个类或结构体有多少个对象,它们的函数都是共有的

    //代码区的函数不计入sizeof

     1 #include <iostream>
     2 using namespace std;
     3 
     4 struct mystr//函数在代码区,无论一个类或结构体有多少个对象,它们的函数都是共有的
     5 {
     6     int a;
     7     int b;
     8     void go()
     9     {
    10         std::cout << "123456789" << std::endl;
    11     }
    12 };
    13 
    14 void main()
    15 {
    16     std::cout << sizeof(mystr) << std::endl;//8
    17         
    18     system("pause");
    19 }

    复习结构体sizeof

    struct mystr
    {
    int a;//4
    double b;//8
    char c;//1->8

    //4+8+8=20
    //20%8!=0
    //24%8==0
    //答案是24
    };

     1 #include <iostream>
     2 using namespace std;
     3 
     4 struct mystr
     5 {
     6     int a;//4
     7     double b;//8
     8     char c;//1->8
     9 
    10     //4+8+8=20
    11     //20%8!=0
    12     //24%8==0
    13     //答案是24
    14 };
    15 
    16 void main()
    17 {
    18     std::cout << sizeof(mystr) << std::endl;//24
    19         
    20     system("pause");
    21 }

    class myclass
    {
    int a;//4
    int b;//4
    double c;//8

    //4+4+8=16
    //16%8==0
    //答案是16
    };

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class myclass
     5 {
     6     int a;//4
     7     int b;//4
     8     double c;//8
     9 
    10     //4+4+8=16
    11     //16%8==0
    12     //答案是16
    13 };
    14 
    15 void main()
    16 {
    17     std::cout << sizeof(myclass) << std::endl;//16
    18         
    19     system("pause");
    20 }

    class myclass
    {
    int a;//4
    double c;//8
    int b;//4->8

    //4+8+8=20
    //20%8!=0
    //24%8==0
    //答案是24
    };

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class myclass
     5 {
     6     int a;//4
     7     double c;//8
     8     int b;//4->8
     9     
    10     //4+8+8=20
    11     //20%8!=0
    12     //24%8==0
    13     //答案是24
    14 };
    15 
    16 void main()
    17 {
    18     std::cout << sizeof(myclass) << std::endl;//24
    19         
    20     system("pause");
    21 }

    引用的sizeof,与引用的对象类型有关。不同于指针

    //引用的本质是指针,直接sizeof引用,就是求引用的数据大小
    //引用变量占据4个字节

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     int num = 10;
     7     double db = 10.9;
     8 
     9     int &rnum(num);
    10     double &rdb(db);
    11     
    12     std::cout << sizeof(rnum) << " " << sizeof(rdb) << std::endl;//4 8
    13         
    14     system("pause");
    15 }

    class myclass
    {
    int &a;//4
    int &b;//4
    char &c;//1

    //4+4+1=9
    //9%4!=0
    //12%4==0
    //答案是12
    };

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class myclass
     5 {
     6     int &a;//4
     7     int &b;//4
     8     char &c;//1
     9 
    10     //4+4+1=9
    11     //9%4!=0
    12     //12%4==0
    13     //答案是12
    14 };
    15 
    16 void main()
    17 {
    18     std::cout << sizeof(myclass) << std::endl;//12
    19         
    20     system("pause");
    21 }

    //引用的本质是指针,直接sizeof引用,就是求引用的数据大小
    //引用变量占据4个字节

     1 #include <iostream>
     2 using namespace std;
     3 
     4 //引用的本质是指针,直接sizeof引用,就是求引用的数据大小
     5 //引用变量占据4个字节
     6 
     7 class myclass
     8 {
     9     char a;//1
    10     char b;//1
    11     char c;//1
    12 };
    13 
    14 class myclass1
    15 {
    16     char &a;//4
    17     char &b;//4
    18     char &c;//4
    19 };
    20 
    21 void main()
    22 {
    23     std::cout << sizeof(myclass) << " " << sizeof(myclass1) << std::endl;//3 12
    24         
    25     system("pause");
    26 }

    //引用右值,节约内存拷贝,内存优化

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int getdata(int && num)//引用右值,节约内存拷贝,内存优化
     5 {
     6     std::cout << num << std::endl;
     7     num += 10;
     8     return num;
     9 }
    10 
    11 void main()
    12 {
    13     int a(5);
    14 
    15     std::cout << getdata(a + 1) << std::endl;
    16 
    17     system("pause");
    18 }

    左值,一般可以取地址就是左值

    右值某些情况可以,某些情况不可以

    1>main.cpp(16): error C2664: “int getdata(int &&)”: 无法将参数 1 从“int”转换为“int &&”
    1> main.cpp(16): note: 无法将左值绑定到右值引用

    std::move将左值转换为右值,C++新语法

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int getdata(int && num)//引用右值,节约内存拷贝,内存优化
     5 {
     6     std::cout << num << std::endl;
     7     num += 10;
     8     return num;
     9 }
    10 
    11 void main()
    12 {
    13     int a(3);
    14     int b(a + 1);
    15 
    16     //std::cout << getdata(a) << std::endl;
    17 
    18     //1>main.cpp(16) : error C2664 : “int getdata(int &&)” : 无法将参数 1 从“int”转换为“int &&”
    19     //    1>  main.cpp(16) : note : 无法将左值绑定到右值引用
    20 
    21     std::cout << getdata(std::move(a)) << std::endl;//std::move将左值转换为右值
    22 
    23     system("pause");
    24 }

    //限定字符串不被修改,指向常量的指针限定了指向的数据无法修改

    //error C3892: “pc”: 不能给常量赋值

    限定一个字符串不被修改,用const char

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     char str[10]("hello");
     7     const char *pc(str);//限定字符串不被修改,指向常量的指针限定了指向的数据无法修改
     8 
     9     std::cout << str << std::endl;//hello
    10     std::cout << pc << std::endl;//hello
    11 
    12     str[3] = 'x';
    13 
    14     //pc[3] = 'y';//error C3892: “pc”: 不能给常量赋值
    15     //*(pc + 3) = 'y';//error C3892: “pc”: 不能给常量赋值
    16 
    17     pc = "world";//可以修改
    18 
    19     std::cout << str << std::endl;//helxo
    20     std::cout << pc << std::endl;//world
    21     
    22     system("pause");
    23 }

    //error C3892: “pc”: 不能给常量赋值

    限定一个数组不被修改,常量引用一个数组

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     char str[10]("hello");
     7 
     8     const char(&rstr)[10](str);//常量引用
     9 
    10     std::cout << str << std::endl;
    11     std::cout << rstr << std::endl;
    12 
    13     str[4] = 'x';
    14 
    15     rstr[4] = 'x';//error C3892: “rstr”: 不能给常量赋值
    16 
    17     std::cout << str << std::endl;
    18     std::cout << rstr << std::endl;
    19 
    20     system("pause");
    21 }

    //引用可以给另外一个引用初始化

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     char str[10]("hello");
     7 
     8     const char(&rstr)[10](str);//常量引用
     9     const char(&rrstr)[10](rstr);//引用可以给另外一个引用初始化
    10 
    11     std::cout << str << std::endl;
    12     std::cout << rstr << std::endl;
    13     std::cout << rrstr << std::endl;
    14 
    15     system("pause");
    16 }

    int(*const & rp)(int a, int b)(p);//引用一个函数指针,限定函数指针不被修改

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int jia(int a, int b)
     5 {
     6     return a + b;
     7 }
     8 
     9 int jian(int a, int b)
    10 {
    11     return a - b;
    12 }
    13 
    14 void main()
    15 {
    16     int(*p)(int a, int b)(jia);//创建一个函数指针,并初始化
    17 
    18     int(*const & rp)(int a, int b)(p);//引用一个函数指针,限定函数指针不被修改
    19 
    20     std::cout << rp(1, 2) << std::endl;
    21 
    22     rp = jian;//error C3892: “rp”: 不能给常量赋值
    23 
    24     std::cout << rp(1, 2) << std::endl;
    25 
    26     system("pause");
    27 }
  • 相关阅读:
    mysql定时删除数据
    【video__播放】视频播放插件video7.4.1使用
    【ueditor__使用】百度ueditor富文本编辑器
    【 CSS__样式收集】常用样式案例收集整理
    【Layui__监听button】在form中监听按钮事件
    【Layui__分页和模板】分页和模板的整合使用
    【Layui__模板引擎】layui.laytpl
    DataTable转list
    反射方法创建委托
    EPPlusHelper
  • 原文地址:https://www.cnblogs.com/denggelin/p/5647789.html
Copyright © 2011-2022 走看看