如何从C++中的函数返回对象引用,以及如何从客户端调用该函数

How to return an object reference from a function in C++ and how to call the function from the client side?

本文关键字:函数 调用 客户端 返回 C++ 对象引用      更新时间:2023-10-16

我正在实现一个名为CurrentUser的成员函数。它将使用用户名作为参数,并返回与给定用户名匹配的User实例对象。以下是代码

User& UserDB::currentUser(string username){
      // userlists is a instance member which is list of user objects
  for(list<User>::iterator i = userlists.begin(); i != userlists.end(); ++i)
 {  
    if(*i.getName().compare(username)==0){
          return *i;
    }
 }
 return null;
}

不确定这样做是否正确。如果错误,请纠正我。谢谢

更新:嘿,伙计们,谢谢你们的建议,我想办法通过返回一个用户指针来做到这一点。这是代码。

User* UserDB::currentUser(string username){
for(list<User>::iterator i = userlists.begin(); i != userlists.end(); ++i)
{     
    if(i->getName().compare(username)==0){
        return i;
    }
}
return null;
}

有几种方法可以做到这一点。

当然,您可以返回指针,但这会让人感到惊讶,因为返回引用或对象更正常。指针为对象消费者提供了许多问题,例如:

  • 如果它为空,我应该得出什么结论?

  • 我应该删除它吗?

等等

返回对某物或某物的引用可以消除这些歧义。

话虽如此,引用不能为空,因此函数必须返回一些内容。如果它没有找到它要查找的项目,它必须向调用者指示。一种方式是例外(即要求该项目在逻辑上是不正确的)。然而,如果商品不在那里是正常情况,那么你不想强迫消费者处理异常情况——这也是一种糟糕的形式。

因此,答案是返回一个封装了可选引用的对象。

boost::optional<User&>就是一个很好的例子,但如果你不想包含boost,那么推出自己的就相当简单了

struct optional_user
{
  using element_type = User;
  using reference_type = element_type&;
  optional_user() : _p(nullptr) {}
  optional_user(reference_type r)
  : _p(std::addressof(r))
  {}
  bool valid() const { return bool(_p); }
  // compares to true if the user is present, false otherwise
  operator bool() const { return valid(); }
  reference_type value() const { 
    assert(_p);
    return *_p;
  }
  // can be used anywhere a User& is required
  operator reference_type () const { 
    return value();
  }
private:
  element_type* _p = nullptr;  
};

现在你的功能变成:

optional_user UserDB::currentUser(string username)
{
  typedef list<User>::iterator Iter;
  for(Iter i = userlists.begin(); i != userlists.end(); ++i)
  {  
    if(i->getName().compare(username)==0)
    {
      return optional_user(*i);
    }
  }
  // return an indicator that the user is not present
  return optional_user();
}

您的呼叫站点变成:

optional_user = users.currentUser("bob");
if (optional_user) {
  do_something_with(optional_user /* .value() */);
}

如果您想特别地返回引用,则在执行离开函数后,您所引用的项必须有生存期。

有几种替代方案:

  1. 函数中的静态局部变量
  2. 使用动态存储器
  3. 在函数外部声明的变量
  4. 传递非常量引用

下面是#1的一个例子:

const std::string& Get_Model_Name(void)
{
  static const std::string model_name = "Accord";
  return model_name;
}

其他选择是按值返回变量(副本)。这不使用引用。返回一份副本
例如:

std::string Get_Manufacturer_Name(void)
{
  return std::string("Honda");
}

您也可以考虑传递参数并修改参数:

void Get_Lunch_Special_Name(std::string& entree_name)
{
  entree_name = std::string("Beef Wellington");
}