我的问题是,何时需要通过引用返回对象?这是因为我们可以通过参数列表本身传递要填充的对象。是否有任何特定的情况,它要求通过引用返回。
关于非成员函数,我问这个问题。
编辑:我知道它在运算符重载中的用法。
答案 0 :(得分:6)
当您希望有一个终端可以访问被引用的对象时,您需要返回作为参考。考虑地图中的operator[]
和用例:
std::map<std::string, int> word_count;
std::string word;
while ( std::cin >> word ) {
word_count[ word ]++;
}
您不希望从地图中提取值,而是访问在这种情况下存储的对象进行修改。许多其他设计也是如此,您需要访问某些内部数据,但您不想复制它:
if ( person.name() == "Pete" ) {
用户不需要复制对象,只需检查对象是否具有具体值。您可以通过按值返回来强制复制,并且语义将相同,但成本较高。或者您可以创建一个局部变量并通过引用将其传递给将填充它的函数,在这种情况下,您不仅会产生复制成本,还会使代码更加繁琐:
std::string name;
person.fill_name( name );
if ( name == "Pete" ) {
正如您可能已经注意到的那样,在成员函数的所有使用中都更加麻烦。
现在,我看到“我用非成员函数问这个”,同样的理由适用于不同的层次。可以将自由站立功能应用于对象,请考虑:
boost::any any = 5;
boost::any_cast<int&>( any )++;
函数any_cast
是一个自由函数,但它将引用返回给另一个实例。如果您需要访问实际对象而不是副本,那么引用就是解决方案。请注意,只有阅读时您不需要参考,您也可以按值返回:
std::cout << boost::any_cast<int>( any ); // will print 6 now
类似地,在函数返回对非参数的对象的引用的所有情况下,但是全局或static
(在函数中返回对具有自动存储的变量的引用是未定义的行为,但在所有情况下它都是这样做是正确的,如果你用任何其他解决方案改变它,语义就不一样了。
答案 1 :(得分:4)
返回对其他地方存在的对象的引用时,例如搜索表的find
函数。
答案 2 :(得分:1)
您也可以将它用于单例(一次创建的静态对象,并在main()
之后发布。例如:
struct A
{
unsigned int veryLongTable[ 1000 ];
};
const A& GetTable()
{
static A *table = NULL;
if ( NULL == table )
{
table = new A;
// write values
}
return *table;
}
答案 3 :(得分:0)
在引号中强调我的
我们也可以传递对象
要填充的对象
你弄错了:一个按值返回的函数可以等同于一个使用引用输出参数的函数,但它的不等同于一个返回的函数参考。即:
T& f();
void f(T&);
// We're not filling anything at all!
f().some_member();
f( ??? );