我的问题是由一个C ++代码推动的,这个代码不是我的,我目前正在努力理解。不过,我认为OO开发人员一般可以回答这个问题(因为我曾经在Java代码中见过这种情况)。
通过代码阅读,我注意到开发人员总是使用副作用(大多数函数都有“void返回类型”,除了getter和一些罕见的情况)而不是直接返回结果。他有时使用返回值,但仅用于控制流(错误代码......而不是异常)。
以下是他的原型的两个可能的例子(伪代码): 对于应该在矩阵M:
中返回浮点值的min,max和avg的函数void computeStatistics(float min, float max, float avg, Matrix M);
OR
void computeStatistics(List myStat, Matrix M);
对于应该返回给定列表中的某些对象的函数,该函数验证某个条件和找到的对象数量:
int controlValue findObjects(List result, int nbObjectsFound, Object myCriteria, List givenList)
我不熟悉C ++,因为你可以在我的非伪代码中看到...而是使用Matlab,可以从函数返回你想要的所有内容,例如int和List并排(这对第二个例子很有用)。我知道在C ++中这是不可能的,这可以解释第二个原型,但它没有解释他可以做的第一个例子的选择:
List myStat computeStat(Matrix M)
最后,这是我的问题: 有什么可能的原因可以激发这种选择?这是一个好的做法,一个会议还是一个发展选择?是否有一种方式优于另一种方式(返回值与副作用方式)?
答案 0 :(得分:2)
就C ++而言:
使用返回值的IMO比通过引用传递值更清晰,并且在大多数情况下,没有开销。 (请查看RVO和Copy Elision)
但是,如果你确实使用了控制流的返回值,那么使用引用并不是一件坏事,对大多数开发人员来说仍然很清楚。
所以我想我们可以说选择权是你的。
请记住,许多开发人员并不知道您的C ++编译器正在做什么黑魔法,因此使用返回值可能会冒犯它们。
答案 1 :(得分:1)
在过去,通常的做法是使用引用参数作为输出,因为返回复杂对象非常慢,没有返回值优化和移动语义。今天我相信在大多数情况下返回价值是最好的选择。
答案 2 :(得分:1)
编写以下内容,前提是我认为列表中的副本不合适。
void computeStatistics(List myStat, Matrix M);
相反(如果列表有副本)你应该。
List myStat computeStat(Matrix M)
然而,如果你的对象上没有副本,那么你可以激发引用call-call方法,然后你就不需要在堆上分配它,而是可以在堆栈上分配它并向你的函数发送指针它
关于:
void computeStatistics(float min, float max, float avg, Matrix M);
我个人认为,最佳实践是一种方法,所以我会这样做:
float min computeMin(Matrix M);
float max computeMax(Matrix M);
float avg computeAvg(Matrix M);
我可以看到在一个函数中完成所有这些操作的唯一原因是因为计算不是单独完成的(在单独的函数中做更多的工作)。
如果你需要在一个方法中有几个返回类型,我会用call-by-reference来做。例如:
void SomeMethod(input1, input2, &output1, &output2, &output3)