C++ 按引用传递时取消对指针的引用

C++ 按引用传递时取消对指针的引用,c++,pointers,reference,C++,Pointers,Reference,当通过引用传递函数时取消引用指针会发生什么情况 下面是一个简单的例子 int& returnSame( int &example ) { return example; } int main() { int inum = 3; int *pinum = & inum; std::cout << "inum: " << returnSame(*pinum) << std::endl; return 0;

当通过引用传递函数时取消引用指针会发生什么情况

下面是一个简单的例子

int& returnSame( int &example ) { return example; }

int main()
{
  int inum = 3;
  int *pinum = & inum;

  std::cout << "inum: " <<  returnSame(*pinum) << std::endl;

  return 0;          

}
int&returnSame(int&example){returnexample;}
int main()
{
int inum=3;
int*pinum=&inum;
std::cout编译器不会“调用”任何东西。它只是生成代码。取消引用指针在最基本的级别上对应于某种加载指令,但在当前代码中,编译器可以轻松地对此进行优化,只需直接打印值,或者直接打印加载
inum
的快捷方式

关于“临时对象”:取消对指针的引用总是给出一个左值


不过,您的问题中可能隐藏着一个更有趣的问题:编译器如何实现将函数参数作为引用进行传递?

您的问题的答案如书面所示

否,此行为已定义。除非程序员明确指定,
new
运算符调用
int
类型的默认构造函数,否则在取消引用指针类型或使用引用类型时,不会调用构造函数

int* variable = new int;
至于实际发生的情况,正如所写,
returnSame(*pinum)
是与
inum
相同的变量。如果您想自己验证这一点,可以使用以下代码片段:

returnSame(*pinum) = 10;
std::cout << "inum: " << inum << std::endl;
指针和引用

int *pinum = & inum;
编译器以相同的方式处理指针和引用,它们的用途不同,实现也不同。指针类型和引用类型将其他对象的位置作为其值存储。指针解引用(使用
*
->
运算符)指示编译器生成跟随指针的代码,并在指针引用的位置而不是值本身上执行操作。取消引用指针时不会分配新数据(不会调用构造函数)

使用引用的工作方式大致相同,只是编译器自动假定您希望值位于该位置,而不是位置本身。事实上,不可能以指针允许的相同方式引用引用指定的位置:一旦指定,引用就无法重置(更改)(也就是说,不依赖于未定义的行为),但是您仍然可以通过在其上使用
&
运算符来获取其值。甚至可能有空引用,尽管处理这些引用特别棘手,我不建议使用它们

片段分析

int *pinum = & inum;
创建指向现有变量inum的指针。指针的值是存储inum的内存地址。创建和使用指针永远不会隐式调用指向对象的构造函数。此任务留给程序员完成

*pinum
取消对指针的引用会有效地生成一个正则变量。该变量在概念上可能占用另一个命名变量使用的相同空间,也可能不占用。在这种情况下,
*pinum
inum
是同一个变量。当我说“products”时,需要注意的是,没有调用构造函数。这就是为什么在使用指针之前必须初始化指针:指针取消引用永远不会分配存储

returnSame(*pinum)
此函数接受引用并返回相同的引用。这有助于认识到此函数也可以使用指针编写,并以完全相同的方式运行。引用也不执行任何初始化,因为它们不调用构造函数。但是,拥有未初始化的引用是非法的,因此运行通过指针调用未初始化的内存不像指针那样常见。可以通过以下方式重写函数以使用指针:

int* returnSamePointer( int *example ) { return example; }
在这种情况下,在传递指针之前不需要取消引用指针,但在打印之前需要取消引用函数的返回值:

std::cout << "inum: " <<  *(returnSamePointer(pinum)) << std::endl;
摘要

  • 指针和引用类型是完成同一任务的两种不同方式
  • 适用于其中一个的大多数陷阱适用于另一个
  • 指针和引用在任何情况下都不会隐式调用引用值的构造函数或析构函数
  • 声明对取消引用的指针的引用是完全合法的,只要指针正确初始化

取消对指针的引用不会创建副本;它会创建一个引用指针目标的左值。这可以绑定到左值引用参数,因此函数会接收对指针指向的对象的引用,并返回对该对象的引用。此行为定义良好,并且没有临时对象是inv解决了


如果它按值接受参数,那么这将创建一个本地副本,并且返回对该副本的引用将是不好的,如果它被访问,则会给出未定义的行为。

我有一个链接的冲动。我不确定是否有必要将该问题否决为遗忘。我们在这里有一个独特的机会来纠正对referec的错误理解作者的评论。@0A0D Downvoting适用于那些几乎无法得出有用答案的问题。对于使用支持指针和引用的语言的早期程序员来说,指针和引用是一个非常常见的绊脚石,并且给出了一个典型的误解实例,这可能是一个非常有用的答案对其他迷路的初学者来说,这太晚了,无法回答,但是:取消引用指针不会创建副本;它会创建一个引用指针目标的左值。这可以绑定到左值引用参数,因此函数接收指针指向的对象的引用,并返回对该对象的引用。这种行为是定义良好。(如果它按值接受参数,则
int& nullRef = *((int *) NULL);      // creates a reference to nothing
bool isRefNull = (&nullRef == NULL); // true