C++ 引用(2)

2022-06-16  本文已影响0人  maskerII

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

1. 引用基本使用

基本语法

Type& ref = val;

注意事项:

//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;

常量引用注意:

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;
}

注意:

上一篇下一篇

猜你喜欢

热点阅读