6

假设我有一个返回一个重要结果和几个不重要结果的函数。我声明了它,以便通过引用返回不重要的结果:

int CalculateStuff(int param1, int param2, int& result1, int& result2);

我想调用这个函数来计算一些东西,但是在调用站点我想忽略不重要的结果。我可以这样做:

...
int dummy1, dummy2;
int result = CalculateStuff(100, 42, dummy1, dummy2);
... // do something with the result

我想考虑另一种不声明虚拟变量的方法:

int result = CalculateStuff(100, 42, *new int, *new int);

这有内存泄漏(不可接受),但比“虚拟”名称更清楚地显示我的意图(忽略结果)具有优势。

那么,如果我这样写会发生什么:

int result = CalculateStuff(100, 42, auto_ptr(new int).get(), auto_ptr(new int).get());

合法吗?执行函数代码时,临时整数是否仍然存在?我应该使用unique_ptr而不是auto_ptr吗?

(请不要建议重构我的代码;我可能会 - 但首先我想了解这些东西是如何工作的)

4

6 回答 6

4

根据 Bjarne Stroustrup 的说法,如果某些参数是可选的,那么将它们设为指针类型是一个理想的情况,这样您就可以NULL在不需要为它们传递参数时传递:

int CalculateStuff(int param1, int param2, int * result1, int * result2);

并使用:

int result = CalculateStuff(100, 42, NULL, NULL);

所有其他替代方案都不会像这个一样好,或者至少不会这个好。

当然,实现CalculateStuff必须检查参数是否NULL存在。

于 2011-10-17T12:02:24.093 回答
4

这是合法的;auto_ptr对象将保持活动状态直到表达式结束(即函数调用)。但它丑得要命。

只需重载您的功能:

int CalculateStuff(int param1, int param2, int& result1, int& result2);
int CalculateStuff(int param1, int param2) { 
    int r1=0, r2=0; 
    return CalculateStuff(param1, param2, r1, r2);
}
于 2011-10-17T12:00:05.103 回答
3

这是我的建议:如果您必须要求 SO 弄清楚代码及其语义的正确性,那么代码无法清楚地表达您的意图

我认为第一个版本(带有dummy1and dummy2)是最透明的,并且显然是正确的。

如果您发现自己反复调用该函数并且不想要可选结果,则可以提供重载:

int CalculateStuff(int param1, int param2, int& result1, int& result2) {}

int CalculateStuff(int param1, int param2) {
  int unwanted1, unwanted2;
  return CalculateStuff(param1, param2, unwanted1, unwanted2);
}
于 2011-10-17T12:02:13.493 回答
3

如果您可以控制该函数,推荐的方法是:返回一个std::tuple(或boost::tuple)所有结果或编写一个不需要额外变量的重载。

于 2011-10-17T12:00:50.203 回答
3

您可以创建一个提供隐式(或显式)转换为int&.

struct ignored
{
   int n;
   operator int&() { return n; }
};

n = CalculateStuff(a, b, ignored(), ignored());

您可以进一步使其成为模板并添加 const 重载。

于 2011-10-17T12:17:08.437 回答
2

这是合法的,但不能保证不会泄漏内存, 例如这里的问题 3。

实现可选输出的正确且惯用的方法是传递一个指针,NULL当您不想要结果时传递,并NULL在写入指针之前在函数中进行测试。

于 2011-10-17T13:05:41.313 回答