美文网首页
C++ 引用(2)

C++ 引用(2)

作者: maskerII | 来源:发表于2022-06-16 21:34 被阅读0次

    引用是c++对c的重要扩充。在c/c++中指针的作用基本都是一样的,但是c++增加了另外一种给函数传递地址的途径,这就是按引用传递(pass-by-reference)

    1. 引用基本使用

    基本语法

    Type& ref = val;
    

    注意事项:

    • &在此不是求地址运算,而是起标识作用。
    • 类型标识符是指目标变量的类型
    • 必须在声明引用变量时进行初始化。
    • 引用初始化之后不能改变。
    • 不能有NULL引用。必须确保引用是和一块合法的存储单元关联。
    //1. 认识引用
    void test01(){
    
        int a = 10;
        //给变量a取一个别名b
        int& b = a;
        cout << "a:" << a << endl;
        cout << "b:" << b << endl;
        cout << "------------" << endl;
        //操作b就相当于操作a本身
        b = 100;
        cout << "a:" << a << endl;
        cout << "b:" << b << endl;
        cout << "------------" << endl;
        //一个变量可以有n个别名
        int& c = a;
        c = 200;
        cout << "a:" << a << endl;
        cout << "b:" << b << endl;
        cout << "c:" << c << endl;
        cout << "------------" << endl;
        //a,b,c的地址都是相同的
        cout << "a:" << &a << endl;
        cout << "b:" << &b << endl;
        cout << "c:" << &c << endl;
    }
    
    //2. 使用引用注意事项
    void test02(){
        //1) 引用必须初始化
        //int& ref; //报错:必须初始化引用
        //2) 引用一旦初始化,不能改变引用
        int a = 10;
        int b = 20;
        int& ref = a;
        ref = b; //不能改变引用
    }
    
    // 数组的引用
    void test03()
    {
        int arr[] = {1,2,3,4,5};
        // 方法1
        // 1.定义数组类型
        typedef int(MY_ARR)[5]; // 数组类型
        // 2.建立引用
        MY_ARR &arref1 = arr;
    
        // 方法2
        // 直接定义引用
        int (&arref2)[5] = arr;
    
        // 方法3
        // 1.定义引用数组类型
        typedef int(&MY_ARR_REF)[5];
        // 2.建立引用
        MY_ARR_REF arref3 = arr;
    }
    

    2. 引用的本质

    引用的本质在c++内部实现是一个常指针.

    Type& ref = val; // Type* const ref = &val;
    

    C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同,只是这个过程是编译器内部实现,用户不可见

    // 发现是引用,转换为 int* const ref = &a
    void testFunc(int &ref)
    {
        ref = 100; // ref 是引用,转换为 *ref = 100;
    }
    void test01()
    {
        int a = 10;
        testFunc(a);
    }
    
    void test02()
    {
        int a = 10;
        int &aRef = a; // 自动转换为 int * const ref = &a;这就说明引用为什么必须初始化
        aRef = 20;     // 内部发现aRef是引用,自动帮我们转换为:*aRef = 20;
    }
    

    3. 指针引用

    指针的引用 是给指针变量取别名

    在c语言中如果想改变一个指针的指向而不是它所指向的内容,函数声明可能这样:

    void fun(int**);
    
    // C语言 二级指针放一级指针变量的地址
    // 被调函数
    void func2(char **temp)
    {
        char *p;
        p = (char *)malloc(64);
        memset(p,0,64);
        strcpy(p, "小花2");
        *temp = p;
    }
    // 主调函数
    void test02()
    {
        char* mp = NULL;
        func2(&mp);
        cout << mp << endl;
    }
    

    在C++中使用指针引用,去改变一个指针的指向,代码更加简洁

    // C++
    void func3(char* &temp) {
        char *p;
        p = (char *)malloc(64);
        memset(p,0,64);
        strcpy(p,"小花3");
        temp = p;
    }
    
    void test03() {
        char* mp= NULL;
        func3(mp);
        cout << mp << endl;
    }
    

    通过引用参数产生的效果同按地址传递是一样的。引用的语法更清楚简单:

    • 函数调用时传递的实参不必加“&”符
    • 在被调函数中不必在参数前加“*”符

    4. 常量引用

    常量引用的定义格式:

    const Type& ref = val;
    

    常量引用注意:

    • 字面量不能赋给引用,但是可以赋给const引用
    • const修饰的引用,不能修改。
    void test01()
    {
        // 普通引用
        int a = 10;
        int &ref = a;
        ref = 20;
    
        // int &ref2 = 10; // 普通引用不能给字面量取名 错误
    
        const int &ref3 = 10; // 可以给const修饰的引用赋予字面量
        // const修饰符修饰的引用的原理
        // 编译器会把上面的代码变为: int tmp = 10; const int &ref3=tmp
    
        int b = 20;
        const int &ref4 = b; // const修饰的引用,不能修改
        // ref4 = 30;
    }
    

    5. 引用的使用场景

    常量引用主要用在函数的形参,尤其是类的拷贝/复制构造函数。
    将函数的形参定义为常量引用的好处:

    • 引用不产生新的变量,减少形参与实参传递时的开销。
    • 由于引用可能导致实参随形参改变而改变,将其定义为常量引用可以消除这种副作用。

    如果希望实参随着形参的改变而改变,那么使用一般的引用,如果不希望实参随着形参改变,那么使用常引用。

    //const int& param防止函数中意外修改数据
    void ShowVal(const int& param){
        cout << "param:" << param << endl;
    }
    

    引用作为函数参数传递数据,节约空间

    // 1. 引用作为函数参数传递数据,节约空间
    
    void func1(int &a, int &b)
    {
        int sum = a + b;
        cout << "sum = " << sum << endl;
    }
    

    引用作为函数的返回值

    int &func3() {
        static int b = 10;
        return b;
    }
    

    注意:

    • 不要返回局部变量的引用
    • 函数当左值,必须返回引用。

    相关文章

      网友评论

          本文标题:C++ 引用(2)

          本文链接:https://www.haomeiwen.com/subject/ckaqvrtx.html