运行 对象调用中的对象调用

Running an object call within an object call

我有一个结构

  struct Stuff {

float something (int& prereq) {
float s = prereq+2;
return s;
}

double something_else(int& prereq_ref, float& thing_ref, float& s_ref ){
s2 = s + thing + h;
return s2;
}

};

然后我 运行 在我的主循环中调用

float thing = 4;  
int prereq = 2;

int main() {

Stuff item;

    double n = item.something_else(prereq, thing, item.something(prereq));
return 0;

}

main 中的调用不会 运行,但下面的行会

float s = item.something(prereq); 
double n = item.something_else(prereq, thing, s);

我是不是遗漏了什么明显的东西?我不想把内存浪费在看似不必要的浮点数上。

float& 是一个 左值引用 类型。它只能取可以赋值的值,比如变量。

float s = item.something(prereq); 
double n = item.something_else(prereq, thing, s);

这里,s是一个变量。它在内存中占有一席之地,表达式 s = ... 将是有意义的。另一方面,

double n = item.something_else(prereq, thing, item.something(prereq));

这里的值是item.something(prereq)不是左值。我们不能写 item.something(prereq) = ...;分配给该函数的 return 值没有意义。

如果您不打算修改函数参数,请通过常量引用或值获取它们。

double something_else(const int& prereq_ref, const float& thing_ref, const float& s_ref)

double something_else(int prereq_ref, float thing_ref, float s_ref)

对于结构或 类 等大型数据,您可以考虑使用 const&,但对于整数和浮点数,这是不必要的开销,按值参数就可以了。

int foo(int & arg);

这个函数签名说: “我将引用您传入的变量,我可能会在计算我的 return 值时更改它。”

如果该声明不正确,那么您的函数签名是错误的,或者至少会误导任何查看它的人。还值得注意的是,如果您计算临时值,它不在变量中,因此没有资格传递给此函数。这就是你 运行 遇到的问题。

请注意,这种风格的函数签名就是所谓的“输出”参数(非常量左值引用),因为它可以被认为是 return 通过参数输出。如果有其他方法可用,则不鼓励使用这种设计方法,因此实际上很少见。任何时候您发现带有非常量引用参数的函数时,请确保这就是您的意思。

与此比较:

int foo(int arg);

这个函数说: “我有自己的副本,不关心它来自什么,变量、引用、临时等等,在计算我的 return 值时,我会保留你的原始值。”

这显然是你想说的,所以在你的参数列表中删除 &