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个语句工作的地方不起作用?
答案 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
。