【问题标题】:Running an object call within an object call在对象调用中运行对象调用
【发布时间】:2021-12-24 12:16:43
【问题描述】:

我有一个结构

  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);

我是否遗漏了一些明显的东西?我宁愿不要把内存浪费在看似不必要的浮点数上。

【问题讨论】:

  • 我认为隐式转换会发生吗?试试item.something_else(prereq, thing, (float) item.something(prereq))
  • something() 按值返回 floatsomething_else() 通过引用接受 float。为此,something_else() 需要接受 const 引用(可以绑定临时值,例如函数的返回值)或 something() 需要返回对 float 的引用,该引用继续返回后存在。

标签: c++ class struct


【解决方案1】:

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) = ...;分配给该函数的返回值是没有意义的。

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

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&,但对于整数和浮点数,这是不必要的开销,按值参数就可以了。

【讨论】:

    【解决方案2】:
    int foo(int & arg);
    

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

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

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

    对比一下:

    int foo(int arg);
    

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

    这显然是你想说的,所以把&放到你的参数列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 2012-06-10
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      相关资源
      最近更新 更多