使用常量修饰符引用

时间:2012-12-24 11:42:26

标签: c++ reference const

FirstOne ::

double & val = 66.6;     //illegal
const double & val = 66.6;   //legal

我只是做了一些演示程序,并通过上述概念,但无法确定上述概念的确切需求。 在第二种情况下,const究竟正在做什么?

SecondOne ::

int nVar = 12;
int &rVar = nVar ;//Ok
double &dVar = nVar ;//Error
const double &cdVar = nVar ;//Ok

为什么第3个语句在第4个语句工作的地方不起作用?

5 个答案:

答案 0 :(得分:6)

第一种是非法的。您不能将非const引用绑定到临时引用。

第二个是合法的。它创建一个临时的double,初始化为66.6,并使val成为对它的const引用。

const承诺不会通过引用更改值。 C ++不允许您将非const引用绑定到临时引用,因为这通常是一个错误。

答案 1 :(得分:3)

让我告诉你。

void f(Base*& p) { p = new Base; }
int main() {
    Derived* d;
    f(d); // Creates temporary Base* and calls f with it
    // Dude, where's my object?
}

正如您所看到的,这引入了一个令人讨厌的错误。首先,对象被泄露且无法恢复,因为f的参数实际上根本没有引用d。其次,即使d中的f成功变异,也会出现错误类型并违反类型系统。

答案 2 :(得分:2)

由于val是对另一个变量的引用,理论上这就像在旧的fortran时代,将1.0传递给函数作为参考(无论在fortran中调用该方法),并且可以将1.0更改为别的。使用1.0作为常量的其他一些代码将使用新值。我会说,不允许这样做是个好主意。

因此,C ++标准只允许对不应修改的任何内容进行常量引用 - 如果稍后执行val += 4.0,您会期望什么效果?常数66.6变为70.6?

编辑:我认为场景是你有一个功能

void func(double &d)
{
    d += 4.0;
}

你不能把它称为:

func(66.6);

所以你试过了:

double &val = 66.6;

这也不起作用?

解决此问题的正确方法是:

double val = 66.6;

func(val);    // compiler makes a reference to val that is passed to func. 

答案 3 :(得分:1)

double & val = 66.6;

这不会编译,你不能绑定对临时的引用。

const double & val = 66.6;

这是有效的,将导致对临时66.6的引用。

我认为没有理由将该值声明为引用,将其创建为const double val = 66.6;,然后如果以后需要将其作为参考传递。

答案 4 :(得分:1)

第二种情况中的const告诉编译器不要复制右边的值。在你的情况下,这没有多大区别(编译器可能会生成相同的代码)。

但在下列情况下,someFunction的结果不会被复制,只会被分配。如果它发生很多或者返回对象的副本很昂贵,这将特别有用。

const double & val = someFunction();

您实际在做的是扩展堆栈上值/对象的“生命周期”,而不是复制它。这被称为“临时”。由于创建值/对象的代码不知道您将使用它,因此必须将其设为const