如何在不生成副本的情况下使用getter和setter?

Tha*_*ain 6 c++ getter-setter

我想知道如何为需要大量内存的成员变量使用getters和setters方法。通常我会像下面这样:

class A
{
private:
  BigObject object;
public:
  BigObject getObject() const
  {
    return object;
  }

  void setObject(const BigObject& object)
  {
    this->object = object;
  }
};
Run Code Online (Sandbox Code Playgroud)

但是,我相信此getter和setter将复制我不想要的BigObject。有一个更好的方法吗?

我想这样做,但是我在互联网上读到这不是一个好主意,因为如果使用不当,可能会导致分割错误:

BigObject& getObject()
{
  return object
}
Run Code Online (Sandbox Code Playgroud)

Nik*_* C. 6

(如果您在这种情况下不关心封装,则意味着该A::object成员可以不受任何限制地被任何人修改,然后查看SergeyA的回答)。

通过const引用返回以避免复制并仍然保持封装(这意味着调用者不能错误地修改成员):

const BigObject& getObject() const
{
    return object;
}
Run Code Online (Sandbox Code Playgroud)

如果呼叫者确实想要复制,他们可以自己轻松进行复制。

如果要防止在临时方法上使用getter时悬挂引用(提到的段错误),则只能在实际在临时方法上调用getter时返回副本:

BigObject getObject() const &&
{
    return object;
}

const BigObject& getObject() const &
{
    return object;
}
Run Code Online (Sandbox Code Playgroud)

调用getObject()临时文件时,它将返回一个副本。另外,您可以通过删除特定的重载完全阻止临时调用getter:

BigObject getObject() const && = delete;

const BigObject& getObject() const &
{
    return object;
}
Run Code Online (Sandbox Code Playgroud)

请记住,这不是保证的安全网。它可以防止某些错误,但不是全部。函数的调用者仍应了解对象的生存期。

顺便说一句,您还可以改善二传手。现在,无论调用者如何传递参数,它都将始终复制对象。您应该按值取值,然后将其移动到成员中:

void setObject(BigObject object)
{
    this->object = std::move(object);
}
Run Code Online (Sandbox Code Playgroud)

但这需要BigObject可移动。如果不是这样,那将比以前更糟。