Исключительная безопасность C ++ — общий указатель

Я пытаюсь реализовать JSON-фреймворк в C ++ и хочу использовать полиморфные концепции. У меня есть класс JSONNode это своего рода контейнер, в котором хранятся другие объекты JSONNode и т. д. Я делаю это с помощью указателей и динамического размещения. Для безопасности исключений я не хочу использовать new/delete но идти с общим указателем повышения. Базовый сценарий добавления элемента (дополнительного объекта 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 *. Как вы думаете? Или есть другие, более распространенные способы реализации этого?

2

Решение

Но это все еще исключение безопасно?

Нет. Если строительство string передать в качестве другого аргумента Add броски, то динамический объект может быть утечка. Не указано, какой аргумент создается первым.

Исходный код гарантирует, что динамический объект назначается интеллектуальному указателю до того, как что-либо еще произойдет: единственное, что может потерпеть неудачу, — это создание самого интеллектуального указателя, в этом случае он удалит объект.

Или есть другие, более распространенные способы реализации этого?

Как правило, лучше использовать make_shared шаблон функции, а не с помощью new сам. Мало того, что он гарантирует безопасность исключений, никогда не выставляя открытый указатель, он также делает более эффективным использование памяти, создавая управляемый объект и общее количество ссылок в одном блоке памяти.

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]