1

我正在设计一个软件工具,其中有一个内存模型,API 用户可以获取模型的对象、查询它们并设置值。

由于模型的所有对象都属于一个模型,并且大部分操作都必须记录和测试等,因此每个创建的对象都必须注册到该Model对象中。Model存储所有对象,因为std::unique_ptr它是它们的唯一所有者。需要时,它会将原始指针传递给用户。

让我担心的是用户调用delete这些指针的可能性。但如果我使用std::shared_ptr,用户仍然可以使用get()和调用delete它。所以也不是很安全。

我想到的另一个选择是通过名称字符串引用对象,或者传递 ObjectReference 对象而不是真实对象,然后可以销毁这些 ObjectReferences 而不会影响实际存储的对象。

这些引用的工作有点像客户端:您告诉他们要做什么,然后他们将请求转发给实际对象。这对开发人员来说是很多额外的工作,但它保护了指针。

我应该担心指针吗?到目前为止,我一直在使用智能指针,但现在我需要以某种方式允许用户访问由中心模型管理的对象,而不允许用户删除它们。

[嗯...也许将析构函数设为私有,并让只有 unique_ptr 可以通过 Deleter 访问它?]

4

2 回答 2

2

您不应该为用户调用delete您的对象而烦恼。这是作为记录约束的那些事情之一,任何违反该约束的程序员都应该遇到他遇到的任何问题。

如果您仍然真的想明确禁止这样做,您可以编写一个轻量级的外观对象,您的用户将通过值传递(但根据您必须包装的类的数量,它可能会做很多工作),或者正如您所说,将它们的析构函数设为私有并unique_ptr使用friend删除器。

我不喜欢只通过标识符工作,这会因为查找时间而迅速导致性能问题(即使您在下面使用地图)。


编辑:现在我想到了,在标识符和原始指针/引用之间有一种方法:不透明引用

从用户的角度来看,它就像一个标识符,他们所能做的就是复制/移动/分配它或将它传递给您的模型。

在内部,它只是一个带有指向您的对象的私有指针的类。您的模型是此类的朋友,它可以从原始指针(用户不能这样做)创建不透明引用的新实例,并使用原始指针访问对象而不会造成任何性能损失。

类似于以下内容:

class OpaqueRef
{
    // default copy/move/assignment/destructor
private:
    friend class Model;
    Object* m_obj;
    OpaqueRef(Object& obj) : m_obj(&obj) {}
};

不过,不确定这是否值得麻烦(我支持我的第一段),但至少你还有一个选择。

于 2013-07-26T10:40:00.227 回答
1

就个人而言,我会将内部指针保留在模型中而不暴露它,并通过模型 id 提供接口,因此所有操作都通过接口进行。

因此,您可以创建一个单独的接口类,允许通过 id 修改模型属性。外部对象只会请求并存储他们想要更改的对象的 id。

于 2013-07-26T10:38:56.960 回答