我和我的上级一直在争论这个功能:
const std::string &GetCurrentDataSourceName(std::string & sName)
{
sName = GetAnotherComponent().GetName();
return sName;
}
是否有任何原因可以包含函数返回类型和参数类型?该函数的目的是返回1个值。
他的动机和用例是人们可以做到这一点:
std::string sName = "";
SetSomeValue(GetCurrentDataSourceName(sName));
我认为最好省略这样的参数:
const std::string &GetCurrentDataSourceName()
{
return GetAnotherComponent().GetName();
}
但他让我怀疑自己的编码能力。
编辑: 返回的值必须是const。代码也已更新,以显示返回值的来源。我来自同一个类中的另一个组件;
答案 0 :(得分:7)
原始功能看起来像一个丑陋的黑客。它肯定会从阅读代码的任何人那里调用“WTF”,因此它应该可以避免。
请注意,您的替换依赖somevalue
作为全局对象或类似对象。如果不是这种情况(即如果在函数内部计算somevalue
),那么你将返回一个悬空参考 - 错误代码。
我认为最干净的方法是摆脱一线启用黑客,依靠移动语义和/或[N]RVO来完成他们的工作,然后按价值返回:
std::string GetCurrentDataSourceName()
{
return somevalue;
}
答案 1 :(得分:5)
似乎函数的重点只是获取一些字符串值,在这种情况下我只会这样写:
std::string GetCurrentDataSourceName() {
return somevalue;
}
除非您有充分理由将const
引用返回somevalue
,否则只需按值返回。如果在函数中计算somevalue
并且您刚刚省略,那么肯定不会返回引用。
我认为没有充分的理由拥有输出参数。你的上司的例子可以这样写:
std::string sName = GetCurrentDataSourceName();
SetSomeValue(sName);
我也觉得这更容易阅读。
答案 2 :(得分:2)
您建议的代码......
const std::string &GetCurrentDataSourceName()
{
return somevalue;
}
...令人担忧,因为它返回对变量的引用,这意味着您必须对somevalue
的生命周期和潜在进一步更改/无效与潜在客户端使用情况有关的深入见解和保证
如果您碰巧返回一个引用来表示static const std::string
存储“组件”名称(如您编辑的问题所暗示的那样),那就没关系了,但它通常不是您想要的东西因为通常引用返回是偶然的,并且引用是一个(调用)函数局部变量,当函数返回时超出范围,所以任何看到上面返回类型的人都会立即对函数感到紧张,至少希望仔细检查实施情况或确保文件提供相关保证。
一般来说,编码更好......
std::string GetCurrentDataSourceName() // "const" here if a member function
{
return ...somevalue..;
}
...哪个 - 如果还需要设置局部变量 - 那么可以这样使用:
SetSomeValue(sName = GetCurrentDataSourceName());
它也更方便,因为调用者不一定需要一个命名的局部变量,如果他们只想要例如将数据源名称传递给另一个函数,在表达式中使用它(例如,添加前缀/引用,转义它以便在URL中使用),或者将其传输到某个地方。
在这种情况下,表面上没有理由同时接受将变量设置为by-reference参数并返回新值。
答案 3 :(得分:1)
我不认为在一行中方便连接函数调用'是这样做的正当理由。
按值而不是const引用更好地返回。特别是当你可以使用c ++ 11时。
std::string GetCurrentDataSourceName(std::string sName)
{
//do some work with sName..
return sName;
}
既然你要修改sName,那么无论如何你都要复制,使用移动语义,你可以像这样用函数调用保存复制开销:
sName = GetCurrentDataSourceName(std::move(sName)); //no copy required