本章会介绍一些C++拓展的非面向对象的功能
- 引用
1 概念
引用从一定程度上讲是指针的平替,几乎被所有的面向对象语言所使用。引用相当于对某一目标变量起"别名"。
操作这个别名,与操作原变量一样。(操作同一块地址)不能有相同别名
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`// b是a的引用`
`int` `&b = a;`
` cout << a <<` `" "` `<<` `&a << endl;` `// 1 0x61fe88`
` cout << b <<` `" "` `<<` `&b << endl;` `// 1 0x61fe88`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/fcc309dba5f152320d0d6032100ef6d2.webp)
2 引用的性质
1)可以改变引用的值,但是不能再次成为其他变量的引用
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`// b是a的引用`
`int` `&b = a;`
`int c =` `3;`
` b = c;` `// 只是单纯的赋值,不是引用,b还是a的引用`
` cout << a <<` `" "` `<<` `&a << endl;` `// 1 0x61fe88`
` cout << b <<` `" "` `<<` `&b << endl;` `// 1 0x61fe88`
` cout << c <<` `" "` `<<` `&c << endl;` `// 1 0x61fe88`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/a4768480461ad590991c663d4e1d1fff.webp)
2)声明引用时,必须要初始化
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`// int &b; // 错误 引用必须要初始化`
` cout << a <<` `" "` `<<` `&a << endl;` `// 1 0x61fe88`
`// cout << b << " " << &b << endl; // 1 0x61fe88`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/cd2bebe5d8725d338df590a98eb24afa.webp)
3)声明引用的时候,不能初始化为null
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`// int &b = NULL; // 错误,引用不能初始化为NULL`
` cout << a <<` `" "` `<<` `&a << endl;` `// 1 0x61fe88`
`// cout << b << " " << &b << endl; // 1 0x61fe88`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/cf807992b1a8c681213c3699a8499e91.webp)
4)声明引用的时候,初始化的值可以是纯数值,但是此时需要使用const关键字修饰引用,表示该引用为常量引用,这样的引用的值不能改变。
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`const` `int` `&b =` `444;`
`// b = 2; // 错误 常量引用的数值不能被改变`
` cout << a <<` `" "` `<<` `&a << endl;` `// 1 0x61fe88`
` cout << b <<` `" "` `<<` `&b << endl;` `// 1 0x61fe88`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/a8a287f0ceb11e6f5c775e44be006656.webp)
5)可以将变量引用的地址赋值给一个指针,此时指针指向的还是原来的变量。
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`int` `&b = a;`
`int` `*c =` `&b;//指针c`
` cout << a <<` `" "` `<<` `&a << endl;` `// 1 0x61fe88`
` cout << b <<` `" "` `<<` `&b << endl;` `// 1 0x61fe88`
` cout <<` `*c <<` `" "` `<< c << endl;` `// 1 0x61fe84`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/357fd56c682c57775cdf09d51ac534b3.webp)
6)可以使用const修饰引用,此时如果原变量的值改变,引用的值也改变
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`int a =` `1;`
`const` `int` `&b = a;`
`// b++; // 错误,b是只读的`
` a++;`
` cout << a <<` `" "` `<<` `&a << endl;` `// 2 0x61fe88`
` cout << b <<` `" "` `<<` `&b << endl;` `// 2 0x61fe88`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/edc832f2ca913315422988a36bf69540.webp)
【思考】
写一个函数,函数有两个参数a和b,函数的功能是交换两个传入的参数【原来变量】的值。
![](https://file.jishuzhan.net/article/1742359938337869825/08c95b4fc31aadc0f0eae5f6d39c6d4a.webp)
#include <iostream>`
`using` `namespace std;`
`//c语言普通模式`
`void` `type1(int` `*a,int` `*b)`
`{`
`int c;`
` c=*a;`
`*a=*b;`
`*b=c;`
`}`
`//c语言异或`
`void` `type2(int` `*a,int` `*b)`
`{`
`*a=*a^*b;`
`*b=*a^*b;`
`*a=*a^*b;`
`}`
`//不会产生副本`
`void` `type3(int` `&x,int` `&y)`
`{`
` x=x^y;`
` y=x^y;`
` x=x^y;`
`}`
`int` `main()`
`{`
`int a =` `1;`
`int b =` `5;`
` cout <<"a="` `<< a <<` `" "` `<<` `&a << endl;`
` cout <<"b="` `<< b <<` `" "` `<<` `&b << endl;`
`// type1(&a,&b);//c语言普通模式`
`// type2(&a,&b);//c语言异或`
`type3(a,b);//不会产生副本`
` cout<<"----------------------"<<endl;`
` cout <<"a="` `<< a <<` `" "` `<<` `&a << endl;`
` cout <<"b="` `<< b <<` `" "` `<<` `&b << endl;`
`return` `0;`
`}`
`
![](https://file.jishuzhan.net/article/1742359938337869825/4fc408c4f7110b5edd904a9283977857.webp)
引用作为参数进行定义的时候,在参数传递时,是不会产生副本的,这样会提高运行效率,我们在正常编程当中,建议使用引用进行传递参数。
引用形参,在不参与计算的情况下,我们建议使用const进行修饰。以达到引用的安全性。