zoukankan      html  css  js  c++  java
  • C++回顾day02---<引用>---待补充

    一:引用概念---引用就是为一个变量起一个别名

    每个变量都是指向一块内存空间的标识,引用就是重新设置一个标识,但是这个标识还是指向同一个内存空间

    和指针类似(其实引用本质就是使用了一个常指针 const int* b; 可修改内存值,不可修改指针地址),都可以直接操作同一块内存
    但是引用的可读性更好,在一些场合可以代替指针

    二:简单使用(同指针一起)

    //1.值传递
    void swap01(int a, int b)
    {
        int temp = a;
        a = b; 
        b = temp;
    }
    
    //2.指针传递
    void swap02(int* a, int* b)
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    
    //3.引用传递
    void swap03(int& a, int& b)
    {
        int temp = a;    //可读性好些
        a = b;
        b = temp;
    }
    
    void main()
    {
        int a1 = 1, b1 = 2;
        int a2 = 1, b2 = 2;
        int a3 = 1, b3 = 2;
    
        swap01(a1, b1);
        swap02(&a2, &b2);
        swap03(a3, b3);
    
        cout << "值传递:" << a1 << " " << b1 << endl;
        cout << "指针传递:" << a2 << " " << b2 << endl;
        cout << "引用传递:" << a3 << " " << b3 << endl;
    
        system("pause");
        return;
    }

    三:函数返回值涉及引用

    (一)当函数返回值为引用(局部变量的引用)

    int& getRef()  
    {
        int a = 10;
        cout << &a << endl;
        return a;    //这是局部变量,一般会在函数结束后被释放栈空间
                     //但是若是返回的类型是引用,则会将该变量保留    <<重点>>
                     //类似其他语言中,只有当该内存空间无变量指向时,才会被回收  <<重点>>
                     //但是返回引用,则说明,将有其他变量指向该内存空间,不允许回收,延长了生命周期  <<重点>>
    }
    void main()
    {
        int a = getRef();    //相当于直接传值出来
        cout << &a << " " << a << endl;
    
        int &b = getRef();    //将b指向局部变量a的地址,延长了变量生命周期   //注意使用引用来接收int &b,那么该函数返回类型必须是引用int& getRef
        cout << &b << " " << b << endl;
    
        system("pause");
        return;
    }

    (二)当函数返回值为引用(static变量的引用)

    由于static变量的生命周期是当前文件,故不局限于某个函数。
    ---既可以作为其他引用的初始值,还可以作为左值进行使用
    int& getRef()
    {
        static int a = 10;
        cout << &a << endl;
        return a;    
    }
    
    void main()
    {
        int &b = getRef();    //将b指向局部变量a的地址,延长了变量生命周期
        cout << &b << " " << b << endl;
    
        getRef() = 15;        //允许作为左值使用
        cout << &b << " " << b << endl;
    
        system("pause");
        return;
    }

    (三)当函数返回值为引用(返回值是形参) //相当于(一)局部变量,这里用于连接内存和引用

    引用归根到底还是对内存的新标识
    int& g2(int* p)
    {
        *p = 100;
        cout << p << endl;
        return *p;  //看返回的是一个值,实际该值存放的内存还是和a1内存是一致的,返回的引用地址也就是这个内存地址
    }
    
    void main()
    {
        int a1 = 101;
        cout << &a1 << " " << a1 << endl;
    
        int& a2 = g2(&a1);  //a2指向返回的内存地址引用
    
        cout << &a2 << " " << a2 << endl;
    
        system("pause");
        return;
    }

    (四)当函数返回值为引用(对象的引用,涉及拷贝构造函数和=操作符重载)---需要补充

    四:常引用const

    (一)使用变量初始化const引用---会将该 引用变量 变为只读

    正常使用

    尝试修改局部变量

    尝试修改引用变量

    (二)常用在为他人提供接口,同C++回顾day01---<const常量重点>

    设置变量内存为只读,不允许使用接口的用户进行数据修改,只可以进行数据读取
    void ReadOnly(const int& a)
    {
        cout << &a << " " << a << endl;
        //a = 110;    //不允许修改
    }
    
    void main()
    {
        int a1 = 100;
        ReadOnly(a1);
    
        a1 = 101;
        ReadOnly(a1);
    }

    四:匿名对象引用(重点:https://www.cnblogs.com/ssyfj/p/10627359.html

    class Test
    {
    private:
        int a, b;
    public:
        Test(int a, int b)
        {
            this->a = a;
            this->b = b;
        }
    
        void getInfo()
        {
            cout << a << " " << b << endl;
        }
    };
    
    Test func1()
    {
        return Test(1, 2);    //匿名对象1
    }
    void main()
    {
        Test T = func1();    //直接将匿名对象用来初始化同类型对象 
                            //会直接将匿名对象设置为这个新的对象    
                            //即匿名对象1没有释放,而是直接变为T对象
        cout << &T << endl;
        T.getInfo();
        system("pause");
    }

    Test& func2()
    {
        return Test(3, 4);    //匿名对象2
    }
    
    void main()
    {
        Test T = func2();    //使用匿名对象来初始化,会直接将匿名对象转变为这个对象T,延长生命周期
        T.getInfo();
    
        Test& T2 = func2();    //若是这里T2是一个引用,则不是直接拷贝赋值,
                            //而是对匿名对象2的内存空间的一个别名,
                            //而这个对象已经被释放了,故结果是随机值
        T2.getInfo();
    
        system("pause");
    }

  • 相关阅读:
    Css预编语言以及区别
    CSS完成视差滚动效果
    理解ASP.NET Core验证模型 Claim, ClaimsIdentity, ClaimsPrincipal
    EF Expression 扩展
    总结 jion,group join 基于方法的查询与查询表达式 对比
    EF 查询表达式 join
    EF中 GroupJoin 与 Join
    css中“~”和“>”是什么意思
    jquery基于form-data文件上传
    针对 easyui boolean 布尔值 的处理
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10625188.html
Copyright © 2011-2022 走看看