【问题标题】:When to use & in C++ when declaring variables?声明变量时何时在 C++ 中使用 &?
【发布时间】:2013-10-19 00:18:55
【问题描述】:

我无法理解何时将 & 与变量一起使用。我认为它改变了该函数的范围,但由于某种原因,这段代码不起作用

void advanceTimeInMinutes(int& hours, int& minutes, int& advances)
{
    if(advances >=60-minutes){
        hours++;
        minutes=60-minutes+advances;
    }else{
        minutes +=advances;
    }
}

它被调用

advanceTimeInMinutes( hour, minute, 50 );

【问题讨论】:

  • “不工作”是什么意思?你得到一个错误,或者......?
  • 是的,它说“无法将参数 3 从 'int' 转换为 'int&'
  • & 表示引用。您不能传递对文字的引用。只需将其声明为int advances
  • @TheWaller 文字值是文字值。喜欢51.23'c'"foo"
  • 如果您不知道什么是文字、引用或指针,您可能想阅读一本好的 C++ 书籍:The Definitive C++ Book Guide and List

标签: c++ reference ampersand


【解决方案1】:

在许多编程语言中,用于引用对象的名称与对象本身不同。一个对象可能有多个名称。

在 C++ 中为一个对象分配多个名称的最直接方法是使用 & 说明符声明一个名称。 (此用法不同于& 运算符;说明符不是运算符。)

当您使用& 声明这些参数时,它们将成为作为参数传递给函数的对象的别名。此类名称称为引用

C++ 有几种(好吧,很多)种类和类别的表达式。两个重要的概念是可修改性和所有权。当您传递对函数的引用时,您可以选择授予它修改对象的权限以及对象的所有权。可修改性由const 说明符的缺席 指示,所有权由使用&& 而不是& 指示(这是C++11 中的新功能)。

不允许一个函数获得对一个只存在短暂存在的对象的可修改的、非拥有的访问,因为它应该能够期望将结果写入这样的对象以返回给调用者。值50 存储在这样一个瞬态对象中。

一种解决方案是使用int const & advances,但更好的解决方案是根本不使用引用,因为您并没有真正尝试使用别名来引用共享对象。


许多人在概念上假设引用是自动取消引用的const 指针。这工作得很好,编译器几乎总是以这种方式做事。但这不一定是真的。例如,给定这个类定义:

struct s {
    static int x;
    int &r = x;
    char c;
};

编译器可以确定r 始终引用全局x,并将每次使用r 替换为x。无需在每个对象中存储引用,sizeof(s) 可以合法地为 1。

这比当前的 C++ 代码分析更先进,但它不可避免地会在某个时候出现。面向未来的代码不应期望引用的实现等同于指针。

【讨论】:

  • 它不是“对象的另一个名称”,因为引用是一个单独的变量,具有自己独特的生命周期。它保存对象的地址,但与指针不同的是自动取消引用,因此您始终访问引用的对象,而不是地址的数值。
  • @BenVoigt 引用是其所指对象的名称,不多也不少。不能保证任何引用都由指针支持。
  • @BenVoigt 不,我的意思是引用不是对象。他们没有存储空间。在结构中分配的用于存储后备指针的任何内存都只是可选的填充。
【解决方案2】:

& 是一个引用运算符。它用于更改函数内部的值。上面的代码等价于

void advanceTimeInMinutes(int *hours, int *minutes, int *advances)
{
    if(*advances >= 60 - *minutes){
        (*hours)++;
        *minutes = 60 - *minutes + *advances;
    }else{
        *minutes += *advances;
    }
}

advanceTimeInMinutes(&hour, &minute, &50);

由于数字没有地址,所以会报错

【讨论】:

  • * 是一个指针运算符。在问这个问题之前,你应该阅读一些基本的 C/C++
  • 在这种情况下,& 不是运算符。同样,* 也不在函数的参数列表中;在正文中,它是取消引用运算符。
【解决方案3】:

您不能将文字值作为引用传递。由于您从未设置 advance 参数,因此不要通过引用传递它,因此请删除该参数的 & (并将其设为 const (有趣的是,如果您将参数设为 @987654324 @ 那么你可以使用参考))。

【讨论】:

  • -1,这并没有提到引用是什么或与&有什么关系,最后一句话与第一句话完全矛盾,两者之间没有和解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
相关资源
最近更新 更多