防止在容器获取副本后使用非常量对象



我有一个函数,它修改一个对象,然后容器复制并存储:

void modifyObjectAndStore(Obj& obj)
{
obj.a = 5;
obj.b = 8;
// there's state set here which isn't possible to set in the caller
_container.takeCopy(obj);
// From this point on obj should not be modified/used directly
}

一旦容器获取并存储了副本,就不应该直接使用obj

什么是确保这一点的最佳方式,或者如果不能做到这一点,就表明意图?

发布我的评论作为答案:


我将通过右值引用传递参数:Obj&& obj

这使您可以将对象移动到容器中,而不是复制它

这也意味着传递给这个函数的参数不应该在调用后使用,但编译器不会强制执行这一点。

如果您一直想要这种行为,请删除复制构造函数和复制赋值。

class Obj
{
public:
Obj(const Obj&) = delete;
Obj& operator=(const Obj&) = delete;
Obj(const Obj&&);
Obj& operator=(const Obj&&);
/* Possibly virtual if this is a base class in a hierarchy */
~Obj();
// Rest of the stuff
};

然而,这将在任何地方禁用复制语义,并且您将被迫像std::unique_ptr<T>一样使用移动语义。

您还应该参考规则5来理解为什么我显式地声明move构造函数和赋值,以及析构函数。

拆分您的函数:

void modifyObjectAndStore(Obj& obj)
{
obj.a = 5;
obj.b = 8;
// there's state set here which isn't possible to set in the caller
_container.takeCopy(obj);
use(_container.back());
}
void use(const Obj& obj)
{

// ...
}

最新更新