Может быть, это только пример кода, к которому это относится, но я не думаю, что пользователь должен предполагать, что ptr
является действительным, когда конструктор X
выбрасывает.С таким же успехом его можно было бы сгенерировать до назначения ref.
Так что я бы сказал, очистите внутренний объект, если можете (то есть, если передняя часть арены в настоящее время находится в конце внутреннего объекта).Хорошо, распределение с арены становится недействительным, что ненормально, но это распределение, которое так или иначе никогда бы не вышло в реальный мир.
Возможно, вы могли бы сделать это явным, с концепцией«мягкое» распределение.Не гарантировано, что жить вечно, потому что, будучи «мягким», его можно вернуть обратно на арену.Тогда конструктор X будет делать что-то вроде:
SoftPtr<std::string> tmp(ptr->SoftAllocate<std::string>());
stuff_that_might_throw();
ref = tmp.release();
Выполнение деструктора SoftPtr
без предварительного вызова release
подразумевает, что никакая ссылка на объект не была открыта.Он вызывает функцию MemoryArena, которая выполняет что-то вроде:
- уничтожает объект
- проверяет, является ли это самым последним выделением с арены
- если это так, вычтите размер из указателя текущей позиции арены
- , если нет, ничего не делайте (утечка памяти)
Таким образом, любое количество выделений может быть "отменено" при условии, что это сделано в обратном порядке.