如果您在这种情况下不关心封装,也就是说A::object
成员应该可以被任何人修改而没有限制,请查看SergeyA的答案。
通过const引用返回以避免复制并仍然保持封装(这意味着调用者不能错误地修改成员):
const BigObject& getObject() const
{
return object;
}
如果调用者确实需要一份副本,他们可以很容易地自己完成。如果你想要防止悬空引用(你提到的segfault)在 getter 被用于临时对象时发生,你只能在 getter 确实被用于临时对象时返回一份副本:
BigObject getObject() const &&
{
return object;
}
const BigObject& getObject() const &
{
return object;
}
在调用临时对象上的getObject()
方法时,将返回一份副本。或者,您可以通过删除该特定重载来完全防止在临时对象上调用getter:
BigObject getObject() const && = delete;
const BigObject& getObject() const &
{
return object;
}
请记住,这不是一种保证安全的措施。它可以防止某些错误,但并非全部。函数的调用方仍应注意对象生存期。
顺便说一下,您也可以改进您的setter。现在,它将始终复制对象,而不管调用方如何传递参数。您应该通过值进行传递,并将其移动到成员中:
void setObject(BigObject object)
{
this->object = std::move(object);
}
这要求
BigObject
是可移动的。如果它不是可移动的,那么这比以前更糟糕。