通过引用“先进”的概念?

时间:2012-11-11 14:37:29

标签: c++ reference

执行此操作时:

int square(int& x) { return x*x;};

int s = square(40); // This gives error

要解决此问题,请执行以下操作:

int square(const int& x) { return x*x;};

int s = square(40); // This is OK

我知道40是常数但是如果我这样做会怎么样:

const int& x = 40 

为什么只有const关键字才可以?这是编译器保护的方式,没有人可以更改x引用的值吗?

40是一个const,所以我们甚至不知道它在内存中的位置,但编译器不应该知道这个地址,因此应该允许将值从40改为30,因为编译器只能去地址&40并将值更改为30?

5 个答案:

答案 0 :(得分:2)

仅仅因为它可以实现并不意味着你应该这样做。 40岁真的是30岁是热闹的,但特别难以维持,不应该被允许。另外,40实际上不一定拥有地址。考虑40个高速缓存,寄存器或立即指令。

答案 1 :(得分:2)

square声明:

 int square(int& x);

采用左值,而square(40)的调用采用右值,这是不一致的,请参阅更多左值和右值here

答案 2 :(得分:2)

有关引用的规则是您不能将临时引用到非const左值引用。文字40可用于初始化临时,但它本身不是对象。因此,您不能将非const左值引用绑定到它。

当你这样做时

int const& value = 40;

您实际将初始化为40的临时对象绑定到引用value。通常情况下,临时表格超出范围并在完整表达结束时被销毁。但是,当您直接将临时绑定到非const引用时,其生命周期将延长以匹配引用的生命周期。

禁止将临时对象绑定到非const引用的规则到位,主要是因为它可能会导致许多令人惊讶的结果。它可以在技术上完成,但很可能产生不明显的结果。

答案 3 :(得分:1)

你会混淆常量和文字。它们相似,但不相同。 40不是常数,而是文字。

您不能通过引用传递文字,因为如果您通过引用传递某些内容,则意味着它可以被修改 - 文字不能。请考虑以下事项:

void foo(int &i)
{
    i = 1;
}

foo(0); // What on Earth? 0 == 1?

但是,如果您传递对常量的引用,则意味着即使它是引用,也不允许该函数修改其参数(因为它是常量),所以现在你可以安全地传入一个文字 - 它现在有意义,,因为该函数不可能修改它的参数。

答案 4 :(得分:1)

你仍然可以这样做:

int x = 40;
int s = square(x)

x = 30;
s = square(x);

两个版本的square(一个或没有const)。

当您通过引用传递内容时,您传递的是现有对象(因为这就是引用意味着现有对象的别名)。

在你的例子中:

int s = square(30);

传递对象。这是一个文字(它们是不是对象)。编译器可以通过创建临时对象将文字转换为对象。但是语言对临时对象有明确的限制,这意味着它们是const。这意味着引用不能传递给它们将被突变的接口(尽管你可以通过const引用传递它们)。