为什么以及在何处在C++中使用引用和指针

Why and where to use reference and pointers in C++

本文关键字:引用 指针 C++ 在何处 为什么      更新时间:2023-10-16

可能的重复项:
C++:何时使用引用与指针

我是C/C++语言的新手程序员,由于我来自C#,Java,JavaScript以及一些Visual Basic和Python的背景,我很难理解C++中的一些东西。

我已经知道如何使用引用和指针以及它们的真正含义等。但我不明白为什么以及在哪里使用它们。我知道引用有时是这样使用的:

int x = 2;
void Square(int &value)
{
   value = value*value;
}
Square(x);
cout << x << endl;

输出将为 4。

我想我不太明白为什么要这样做而不这样做:

int x = 2;
int Square(int value)
{
   value = value*value;
   return value;
}
x = Square(x);
cout << x << endl;

无论如何,我希望有人能够帮助我理解为什么以及在何处使用引用和指针。

传递引用有两个主要原因:

  • 更改函数内引用的对象的值
  • 避免复制传递的对象的成本

如果您想要第二个好处而不是第一个好处,您通常会传递一个const引用以避免错误地更改传递的对象。

在C++中,指针和引用大致相同,但有两个例外:

  • 引用不能指向 0(或 nullptr
  • 引用必须始终指向同一对象

如果要执行这些操作之一,则必须使用指针。

此外,指针通常指向使用 new 在堆中创建的对象,而引用通常指向在堆栈中创建的对象。这意味着指针指向的对象的生存期通常是手动控制的。您必须对 new 创建的对象显式调用 delete 才能销毁它们,但在堆栈中创建的对象的生存期由运行时自动管理(因此它们称为"自动变量")。

我不知道这是否是您需要知道的全部内容,或者您正在寻找更具体的东西。

这样的例子没有实际区别,但不是将整数传递给Square(),而是 imagine square 是一种复杂的算法,需要 10 GB 的数据。使用指针不是更好吗,这样参数就不会被复制?

将参数作为引用传递意味着您将修改其值(如果您对其执行某些操作),而不是作为其副本的变量。由于您使用 &value,它会更改存储在 &value 指向的地址处的内容。

你需要在 Squre() 中传递 &x 来代替 x。

所以 x= Squre(&x);

Squre(&x);

是一样的。

当您

想要使用其他名称引用变量时,将使用引用。 它们具有完全相同的类型、值等。
指针有些不同,它是一种存储地址的新类型。

int i;  
Int &ref = i;  
Int *pointer = &i;  

那么 ref 和 *pointer 实际上是一回事,即 i 的值。
但是你必须知道,字面上的"ref"只是"i"(初始化后永远不会改变),但"指针"只是暂时指向i。
所以在大多数情况下,它们是一回事。
那么我们什么时候使用引用或指针呢?
在我看来,使用哪个更方便。
例如,引用不能更改,但指针指向不同的事物。 ^_^
啊,忘了抄袭的费用,请检查对方的答案。

第二个示例将使本地复制变量x(仅在函数Square内可见)。

如果您想确保您的全局x保持不变,请这样做。但是,它可能很昂贵(如果您的变量是更大的对象/结构)...和冗余 - 查看关键字const

引用只是变量的伪名称。应用于引用的任何操作实际上都会影响您引用的变量

int a = 5;
int &b = a;
b++; // 'a' gets equal to 6

在您的示例中,您返回乘法的结果,但是如果您需要更改传递给不返回任何内容的函数的变量的值怎么办?

这是引用变得方便的时候。指针的行为方式类似,只是指针不是变量的伪名称,而是它的地址。您可以将指向变量的指针传递给函数,取消引用它,它将以完全相同的方式影响您的变量。

好吧,对于 POD 结构,您不会看到很多好处,因为操作=很容易理解。

所以你的x = square(x)几乎按照它所说的去做,性能相当不错。

当您将对象传递给方法时,使用指针/引用的优点就出现了。在这种情况下:

Object x;
Object squre( Object x )
{
    x._internalvalue = x._internalvalue * x._internalvalue;
    return x;
}
x = squre(x);

这里发生的过程完全不同:=符号不会自动应用于对象,因此您必须实现所谓的三法则,您将在其中找到赋值运算符。但是,赋值运算符非常昂贵,因为它必须在内存中重新创建一个新的(临时)对象,调用赋值运算符,然后将该对象的内存复制回原始x

此外,将对象作为函数的

参数传递将强制处理器复制该对象在堆栈上占用的整个内存,以便在函数中访问它,这是非常昂贵的。

因此,为了回答您的问题,当您开始操作结构和对象时,您开始看到使用引用和指针的好处,它们比普通的旧整数大得多。

使用引用进行编程将提高性能,并限制操作大型对象时堆栈溢出的风险。