更改函数中的变量与返回值

Changing variable in function vs return

本文关键字:变量 返回值 函数      更新时间:2023-10-16
int foo() {return 5;}
void bar(int *var) {*var = 5;}
int main()
{
int lvar;
lvar = foo();
bar(&lvar);
return 0;
}

foo还是bar是更好的选择?foo的好处在于,它不仅可以用于更改变量值。但有时这也更安全,因此函数不会被误用。那么性能呢?

在做出此决定时,我不会将性能视为最高优先级。无论如何都有RVO,一般来说,在分析之前不应该进行优化。

也就是说,imho最大的区别是调用代码的外观:

int f = foo();

int x;
bar(x);

当调用一个返回值的函数时,其意图在调用代码中非常清楚。即使你不知道foo在做什么,你也不必查它就知道它返回了一个int,并且取零参数。另一方面,看看对bar的调用。它做什么?它会改变a的值吗?对bar的调用可能在一个更大的代码块中,为了理解该代码块,您必须查找bar实际在做什么。如果你把两者都混在一起,情况可能会更糟:

int foobar(int& x);

我不建议你写这样的函数,因为在调用代码中

int x;
int y = foobar(x);

可以预期CCD_ 10只是一个不改变的参数。除此之外,调用者经常被迫为一个简单的函数调用编写更多的代码,因为他必须在调用函数之前声明返回值。

结论:传递对返回值的引用会混淆调用代码。

另一方面,在某些情况下,传递引用是可行的。我不时使用的模式如下:

struct MooInput {};
struct MooResult{};
void moo(const MooInput& a, MooResult& b);

现在有了正确的名称,调用者至少有机会编写代码,这样就可以清楚地知道输入了什么,返回了什么:

MooInput a;
MooOutput b;
void moo(a,b);

PS:如果函数获取参数,对其执行一些操作并返回结果,则注意事项有点不同,例如

int Boo ( int x) { return x++;}

在这种情况下,我通常还倾向于提供一个:

void Coo(int& x) { x++; }

因为调用者可能需要两个版本中的一个,这取决于他在调用函数后是否需要旧值。如果只有Boo,并且调用者不需要旧值,那么他将被迫制作一个副本(实际上是一个赋值):

int x;
x = Boo(x);

而如果只有Coo,并且他需要旧的值,他也需要制作一个副本:

int x;
int y = x;
Coo(x);