如何从C++中的函数返回对象引用,以及如何从客户端调用该函数
How to return an object reference from a function in C++ and how to call the function from the client side?
我正在实现一个名为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的一个例子:
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");
}
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销