Исключительная безопасность:

Я хотел бы попросить несколько советов относительно безопасности исключений. В частности, я ссылался Вы (действительно) пишете код безопасности исключений?. Если у меня есть контейнер указателей на объекты типа Node, и я должен был очистить и повторно инициализировать этот контейнер объектов _nodes с новым набором объектов, будет ли этот код безопасным для исключений?

std::vector<Node*> nodes;

for (int i = 0; i < 10; i++)
{
try
{
// New can throw an exception. We want to make sure that if an exception is thrown any allocated memory is deleted.
std::unique_ptr<Node> node(new Node());
Node* n = node.get();
nodes.push_back(n);
node.release();
}
catch (std::exception& exception)
{
// If an exception is thrown, rollback new allocations and rethrow the exception.
for (std::vector<Node*>::iterator it = nodes.begin(); it < nodes.end(); it++)
{
delete *it;
}

nodes.clear();
throw exception;
}

}

_nodes.swap(nodes);

// Delete the unused (previous) objects from the swapped container.
for (std::vector<Node*>::iterator it = nodes.begin(); it < nodes.end(); it++)
{
delete *it;
}

Я также читал в RAII, но я не знаю, как это будет работать, где мне нужен полиморфизм (http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping).

0

Решение

Это намного сложнее, чем нужно. Я бы начал так:

std::vector<std::unique_ptr<Node>> nodes(10);
for (auto& p : nodes)
p.reset(new Node());

Если построить вектор или выделить Node кидает потом все будет вычищено автоматически.

Теперь, если вы разумны и заменить _nodes с std::vector<std::unique_ptr<Node>> тогда остальные функции просто:

_nodes.swap(nodes);

В противном случае это не так просто:

std::vector<Node*> nodes2;
nodes2.reserve(nodes.size());
for (auto p : nodes)
nodes2.push_back(p.release());
_nodes.swap(nodes2);
for (auto p : nodes2)
delete p;

Предполагая, что Node деструктор не может бросить, единственный шаг здесь, который может бросить это reserve звоните так, если это бросает nodes очищен, потому что он держит unique_ptr объекты. После этого вы можете безопасно передать право собственности на nodes2, затем поменяйте местами, затем уберите.

Я также читал в RAII, но я не знаю, как это будет работать, где мне нужен полиморфизм

Мой код выше опирается на RAII, полиморфизм не имеет значения. В приведенном выше коде нет необработанных указателей, которые не принадлежат типу RAII (кроме _nodes, который вы должны изменить, чтобы быть std::vector<std::unique_ptr<Node>>) поэтому, если выбрасывается исключение, все очищается, нет необходимости перехватывать исключение и выполнять очистку вручную.

1

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

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

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