1—C++学习笔记-引用


  斑马斑马      69   
  2020-12-11      C++      

1—C++学习笔记

最近开始由C过渡到了C++,陆陆续续记一些笔记:

引用变量是什么?

​ 引用变量是一种复合类型,相当于给变量起一个 别名 ,这个概念是C++和C不一样的地方之一。
比如:

#include<iostream>
#include<string>
using namesplace std;
int main()
{
    string Person='Xavi';
    string &Handsome_boy=Person;
    system("pasuse");
    return 0;
}

这块代码里,我们有一个变量Person,它的内容是‘Xavi’。可是,一般人看到Handsome_boy这个变量名,也会想到Xavi,这该怎么办。于是,我们可以给Xavi起另一个代号。这里,就使用了引用。

引用的语法

数据类型 &别名 = 原名

  string &Handsome_boy=Person;

引用和指针的差别

如果我们利用&来取出Person和Handsome_boy的内存地址,就会发现他们的地址是一样的。因为我们并没有生成一个新的变量,我们只是给Xavi起了一个别名。很显然,这玩意和指针很像,如果熟悉他的用法的话,也就知道它可以做到在函数内部改变实参,做和指针一样的活。
但是,引用和指针有个很大的差别,这也是引用的几个 注意事项 :

  1. 引用必须初始化,别名总得知道是给谁的吧,听说过无名之辈,没听说过无辈之名啊

  2. 引用一旦初始化,和某个变量关联起来了,就不可以在修改 对,感觉和const指针更像,而不是普通指针。

引用可以作为函数参数,从而让形参修饰实参

#include<iostream>
#include<string>
using namespace std;
void Swap(string& a ,string& b);
int main()
{
    string Xavi = "NormalPerson"; 
    string Zhang = "HandsomeBoy";
    swap(Xavi, Zhang);
    cout << "Xavi:" << Xavi << endl;
    cout << "Zhang:" << Zhang << endl;
    system("pause");
    return 0;
}
void Swap(string& a , string& b)
{
    string temp;
    temp = a;
    a = b;
    b = temp;
}

引入同样可以做到传入指针一样的效果,可以简化代码。
还有一点,由于引用时,函数的形参相当于是一个变量的别名,所以如果我们传入的不是一个变量,就会报错:

#include<iostream>
#include<string>
using namespace std;
void try1(int& a);
int main()
{
    int z = 10;
    try1(z + 1);
    system("pause");
    return 0;
}
void try1(int& a)
{
    cout << a << endl;
}

引用做函数返回值

//返回局部变量引用
int& try1() {
    int a = 10; //局部变量
    return a;//这里函数会返回一个指向临时变量(a)的引用
}

//返回静态变量引用
int& try2() {
    static int a = 20;
    return a;
}

这里要注意的是 不要返回局部变量引用 ,因为局部变量存放在栈区中,栈区开辟的数据由编译器自动释放。编译器会预留一次栈区的数据,也就是说这个函数运行完了,栈区的数据会被暂时保留,如果你用了一次,他就彻底被释放了。而引用是将别名指向原数据的地址,原数据被释放了,别名就变成“无辈之名”了。
总的来说:不要返回局部变量的地址,不要返回局部变量引用,避免返回函数终止时不再存在的内存单元引用

如何来用函数返回一个引用,而且不会出现一系列问题呢?

  1. 返回一个作为参数传递给函数的引用:
#include<iostream>
#include<string>
using namespace std;
int &try1(int& a);
int main()
{
    int z = 10;
    int &q=z;
    int v=try1(z);
    cout<<v<<endl;
    system("pause");
    return 0;
}
int &try1(int& a)
{
    a++;
    return a;
}
  1. 第二个办法是用new来分配新的存储空间。 我们要知道,new是在堆区开辟空间,而堆区的空间由程序员手动开辟,手动释放(delete)。
   int try1(int& a)
{
    a++;
    int* point=new(int);
    *point=a;
    return *point;
}

还有一个办法是返回静态变量,也就是使用static来声明一个静态变量,存放在static静态存储区。堆区和静态存储区的地址很接近,存放在这两个地方的变量的生命周期是有程序员来决定的,我不释放它,它就没有死亡的权利,除非这个程序结束。

   int& try2() {
    static int a = 20;
    return a;
   }

引用的本质

C++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了。

常量引用

如果我在函数里传入的是个常量然后引用它呢,总不能把我这个常量给改了吧。
所以常见用法是,

void showValue(const int& v) {
    cout << v << endl;
}

编译器帮我们优化了代码,int temp = 10; const int& ref = temp;
本身引用不可改变指向,但可以改变指向的值,在前面再加一个const,就连值也不可以修改了。

函数使用const引用参数和按值传递结构的区别

如果函数本身没有修改传入参数的作用,可用 **const xxx & xxx **的形式传值,这比复制原始结构的拷贝相比要更加节省时间和内存

函数返回引用作为左值

int &try1(int& a)
{
    a++;
    return a;
}
try1=4;

这种写法是可行的,看着很诡异,但如果抓住引用的本质是变量的别名,返回一个引用就相当于返回一个变量的别名,那么就不会奇怪太久。首先,函数返回的是一块可修改的内存块,而左值的条件就是这个。因此,这没有问题。
个人拙见,如果错误,还请看官佬爷不吝赐教~
作者:Xaviiiii

ps:以上是1—C++学习笔记-引用全部内容,希望文章能够帮你解决1—C++学习笔记-引用所遇到的游戏开发问题。
本文收录在 游戏编程 🕹️ - 学习C++专题,分享走一走~

猜你喜欢 全系列


您可以在登录后,发表评论