HOUR 12 Creating References

本文深入讲解C++中的引用概念,包括引用的创建、使用及与指针的区别,并通过实例演示如何利用引用传递函数参数,实现更高效的数据交换。

What is reference?

reference 和 pointer 功能差不多,但语法简单,本质就是一个别名(alias), 是之前存在的一个object的代理,对reference做的事情相当于直接作用于对被引用对象。

Creating reference

规定:reference的命名是前置一个r

int &rSomeRef = someInt;

reference必须初始化,否则编译器报错。

区分:

声明中,&代表引用,*代表指针

语句中,&代表区地址,*代表乘法

Using the Address of Operator on References

Again, 引用是一个别名,对应用取地址,返回的是被引用对象的地址。

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int age = 8;
    int &rAge = age;

    std::cout << "address of age is " << &age << std::endl;
    std::cout << "address of rAge is " << &rAge << std:: endl;


    return a.exec();
}

  对引用和被引用对象取地址返回同一地址。

#include <QCoreApplication>
#include <iostream>

int main(int argc, char *argv[])
{
    using namespace std::endl;
    QCoreApplication a(argc, argv);
    int age = 88;
    int &rAge = age;
    int tall = 170;
    rAge = tall;//not what you think!
    return a.exec();
}

  蓝色部分程序员本意可能想,让rAge成为tall的引用,然而,引用只能在创建的时候初始化,其余时间就一直充当引用的作用,也就是说,这句相当于把tall的值赋值给age。

这个语句等价于: age = tall;

What can be referrenced?

可以引用的是OBJECT 

不能引用的是CLASS/TYPE

可以有空指针,不可以有空引用

Passing function arguments by references

之前学习的函数有两个缺点:

  • 通过值传递(只是copy到了子函数)
  • 只有一个返回值

通过引用传递可以规避这两个缺点。

 1 #include <QCoreApplication>
 2 #include <iostream>
 3 
 4 void swap(int *pX, int *pY);
 5 
 6 int main(int argc, char *argv[])
 7 {
 8     QCoreApplication a(argc, argv);
 9     int x = 5, y = 10;
10     std::cout << "the value before swap is \nx = "
11               << x << "\ny = " << y << std::endl;
12     swap(&x, &y);
13 
14     std::cout << "the value after swap is \nx = "
15               << x << "\ny = " << y << std::endl;
16 
17 
18     return a.exec();
19 }
20 
21 void swap(int *pX, int *pY)
22 {
23     //display the value befroe swap
24     std::cout << "the value before swap is:\n*pX =  "
25               << *pX << "\n*pY = " << *pY << std::endl;
26     int temp = *pX;
27     *pX = *pY;
28     *pY = temp;
29     //display the value after swap
30     std::cout << "the value after swap is:\n*pX = "
31               << *pX << "\n*pY = " << *pY << std::endl;
32 
33 }
通过指针传递

 

指针传递虽然能实现两数据交换,但是频繁的进行反引用容易出现错误;调用这个函数要用取地址,封装性不好

C++的目标就是让你只关心这玩意儿是干什么的,返回的是什么。通过指针传递参数,让主调函数很烦啊,打个&&累死人,不小心忘了还容易

下面演示一下引用大法好,直接把刚刚的问题全部解决掉。核心 void swap(&rX, &rY);

 1 #include <QCoreApplication>
 2 #include <iostream>
 3 
 4 void swap(int &rX, int &rY);
 5 
 6 int main(int argc, char *argv[])
 7 {
 8     QCoreApplication a(argc, argv);
 9     int x = 5, y = 10;
10     std::cout << "the value before swap is \nx = "
11               << x << "\ny = " << y << std::endl;
12     swap(x, y);
13 
14     std::cout << "the value after swap is \nx = "
15               << x << "\ny = " << y << std::endl;
16 
17 
18     return a.exec();
19 }
20 
21 void swap(int &rX, int &rY)
22 {
23     //display the value befroe swap
24     std::cout << "the value before swap is:\n*pX =  "
25               << rX << "\n*pY = " << rY << std::endl;
26     int temp = rX;
27     rX = rY;
28     rY = temp;
29     //display the value after swap
30     std::cout << "the value after swap is:\n*pX = "
31               << rX << "\n*pY = " << rY << std::endl;
32 
33 }
通过引用传递

 对比一下这两个程序的第12行,对主调函数来说,不用去concern太多,这才是好函数

函数通过引用返回多个返回值

 1 #include <QCoreApplication>
 2 #include <iostream>
 3 
 4 enum ERR_CODE {SUCCESS, ERROR};
 5 ERR_CODE factor(int n, int&rSquared, int&rCubed);
 6 //number 采用传值,其目的是防止函数修改number
 7 
 8 int main(int argc, char *argv[])
 9 {
10     QCoreApplication a(argc, argv);
11 
12     int number, squared, cubed;
13     ERR_CODE result;
14 
15     std::cout << "Enter a number(0-20): ";
16     std::cin >> number;
17 
18     result = factor(number, squared, cubed);
19 
20     if (result == SUCCESS)
21     {
22         std::cout << "number = " << number << std::endl;
23         std::cout << "squared = " << squared << std::endl;
24         std::cout << "cubed = " << cubed << std::endl;
25     }
26     else
27     {
28         std::cout << "Error encountered!" <<  std::endl;
29     }
30 
31     return a.exec();
32 }
33 
34 ERR_CODE factor(int n, int &rSquared, int &rCubed)
35 {
36     if(n > 20)
37     {
38         return ERROR;
39     }
40     else
41     {
42         rSquared = n * n;
43         rCubed = n * n * n;
44         return SUCCESS;
45     }
46 }

这里的枚举类型的使用应该学习一下,使得程序更加的易读。另外,函数的设计思想也要学习,这里进入函数后首先判断传入参数是否合法,返回值不是客户想要的数值,而是flag,用户的值通过引用直接赋值了。讲究。

Q&A

Q. 既然有了指针了,为何要用引用?

A. 引用不需要用户频繁的去dereference,用指针的玩家===*pNumber = 99; , 用引用的玩家 rNumber = 99;

Q. 你说引用大法好,为什么要有指针?

A. 引用不可以重新赋值,引用不可以为NULL,指针提供灵活的使用方法,就是有点儿费劲。

Q. 传值的方法好处是啥?

A. which prevents the function from changing the original value

 

 

 

 

转载于:https://www.cnblogs.com/a-cock/p/8588860.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值