异常安全C++共享指针

Exception safety C++ shared pointer

本文关键字:指针 共享 C++ 安全 异常      更新时间:2023-10-16

我尝试在C++中实现一个JSON框架,并希望利用多态概念。我有一个类JSONNode,它是一种存储其他 JSONNode 对象本身等的容器。我正在使用指针和动态分配来执行此操作。为了异常安全,我不想使用new/delete而是使用boost共享指针。将元素(另一个 json 对象)添加到 json 对象的基本方案如下所示:

typedef boost::shared_ptr<JSONNode> JSONNodePtr;   
void JSONNode::Add(JSONNodePtr nodePtr, const std::string& name)
{
    this->elements[name] = nodePtr;  // store in STL std::map
}
// create and add json object 
JSONNodePtr obj(new JSONNode());
JSONNodePtr element(new JSONNode());
obj->Add(element, "firstElement");

为了便于使用,我宁愿在没有显式分配element的情况下执行此操作,并将共享指针的创建放入类方法中Add

void JSONNode::Add(JSONNode* node, const std::string& name)
{
    JSONNodePtr nodePtr(node);
    this->elements[name] = nodePtr;
}
// create and add json object 
...
obj->Add(new JSONNode, "firstElement");    

但这仍然安全吗?我想不是因为共享指针的创建不是通过分配 JSONNode* 立即完成的。你觉得怎么样?还是有其他更常见的方法来实现这一点?

但这仍然安全吗?

不。如果构造string作为另一个参数传递给Add抛出,那么动态对象可能会泄漏。未指定首先创建哪个参数。

原始代码确保在发生任何其他事情之前将动态对象分配给智能指针:唯一可能失败的是创建智能指针本身,在这种情况下,它将删除该对象。

还是有其他更常见的方法来实现这一点?

通常,最好使用 make_shared 函数模板,而不是自己使用new。它不仅通过从不公开裸指针来保证异常安全,而且还通过在单个内存块中创建受控对象和共享引用计数来更有效地利用内存。

obj->Add(boost::make_shared<JSONNode>(), "firstElement"); // or std:: in C++11