Как обеспечить (как try-finally) уничтожение объекта HEAP-ALLOCATED - PullRequest
3 голосов
/ 31 августа 2011

Я ищу способ убедиться, что объект, который выполняется в куче, ВСЕГДА освобождается, когда я закончу с ним.

Я знаю, что если он размещен в стеке, я могу использовать RAII, чтобы убедиться, что о нем позаботятся - к сожалению, это не сработает для меня (по крайней мере, напрямую), поскольку рассматриваемый объект фактически создается путем вызова API-функция, которая затем возвращает указатель на объект, который она создает в куче.

Итак, концептуально, что я хочу сделать, это что-то вроде:

TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
try
{
    doStuffWithMyObjThatMayError(p_myObj);
}
finally
{
    delete p_myObj;
}

Единственное, что я могу придумать, - это создать некий фиктивный класс очистки и создать его экземпляр в стеке:

class MegaMaid
{
private:
    TheApi::ApiObject* toFree;
public:
    MegaMaid(TheApi::ApiObject* toFree)
    {
        this->toFree = toFree;
    }

    ~MegaMaid()
    {
        delete toFree;
    }
};

void doStuff()
{
    TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
    TheApi::ApiObject* p_myObj;
    MegaMaid cleaner(p_myObj);
    doStuffWithMyObjThatMayError(p_myObj);
}

Есть ли лучший способ сделать это? Или это принятое решение?

Ответы [ 2 ]

6 голосов
/ 31 августа 2011

Вы все еще можете использовать RAII для указателей, возвращаемых функциями. Вы можете использовать умные указатели (которые в точности соответствуют описываемому вами фиктивному классу) следующим образом:

std::unique_ptr<TheApi::ApiObject> p_myObj(TheApi::createAnApiObj());
6 голосов
/ 31 августа 2011

Этот «фиктивный класс» известен как «умный указатель».Вы должны проверить std::auto_ptr или boost::shared_ptr.Они обеспечивают именно то, что вы ищете.

...