运行 对象调用中的对象调用
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 值时,我会保留你的原始值。”
这显然是你想说的,所以在你的参数列表中删除 &
。
我有一个结构
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 值时,我会保留你的原始值。”
这显然是你想说的,所以在你的参数列表中删除 &
。