RAII классы для варки - PullRequest
1 голос
/ 19 мая 2011

Написание кода на Brew, когда в нем используются локальные интерфейсы, может быть повторяющимся и подверженным ошибкам, чтобы сделать его устойчивым, например:

Foo()
{
ISomeInterface* interface = NULL;
int err = ISHELL_Createnstance(…,...,&interface);

err = somethingThatCanFail();
if (AEE_SUCCESS != err)
    ISomeInterface_Release(interface);

err = somethingElseThatCanFail()
if (AEE_SUCCESS != err)
    ISomeInterface_Release(interface);

etc....

Было бы быстро написать класс RAII для автоматического освобожденияинтерфейс при выходе из функции, но он будет специфичным для конкретного интерфейса (он, конечно, вызовет ISomeInterface_Release в своем деструкторе)

Есть ли способ создания универсального класса RAII, который можно использовать для интерфейсовРазличные типы?т. е. есть ли общая функция Release, которую можно вызывать в RAII вместо конкретной версии интерфейса, или какой-то другой механизм?

--- Edit ---- Извинения, я изначально добавил теги C ++ и RAIIна эту запись, которую я сейчас удалил.В качестве ответа требуется знание Brew, а не знание C ++.Спасибо людям, которые нашли время, чтобы ответить, я должен был добавить больше информации для начала и не добавлять эти дополнительные теги.

Ответы [ 2 ]

3 голосов
/ 19 мая 2011

shared_ptr делает то, что вы просите:

ISomeInterface* interface = NULL;
int err = ISHELL_Createnstance(…,...,&interface);
std::shared_ptr<ISomeInterface*> pointer(interface, ISomeInterface_Release);

Ссылка: http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm#constructors

<ч /> РЕДАКТИРОВАТЬ Вот образец:

#include <cstdio>
#include <memory>

int main(int ac, char **av) {
  std::shared_ptr<FILE> file(fopen("/etc/passwd", "r"), fclose);
  int i;
  while( (i = fgetc(file.get())) != EOF)
    putchar(i);
}
2 голосов
/ 19 мая 2011

Класс RAII, который вызывает указанную функцию в деструкторе, может выглядеть следующим образом:

template<typename T, void (*onRelease)(T)>
class scope_destroyer {
    T m_data;

public:
    scope_destroyer(T const &data) 
        : m_data(data)
    {}

    ~scope_destroyer() { onRelease(m_data); }

    //...
};

Затем вы просто передаете тип T (например, Foo*) и функцию, которая может быть вызвана с помощью одного параметра типа T и освобождает объект.

scope_destroyer<Foo, &ISomeInterface_Release> foo(CreateFoo());
...