Освободить ресурс при форсировании :: shared_ptr - PullRequest
1 голос
/ 17 сентября 2010

Я получаю shared_ptr из библиотечного вызова и передаю его и некоторые ресурсы обратно в библиотеку. Ресурс может быть удален только тогда, когда shared_ptr удаляет свой указатель:

std::ofstream* out = new std::ofstream(); 
...
shared_ptr<Lib::SomeClass> writer = Library.createWriter(out);

Library.appendWriter(writer);

Библиотека ожидает, что я справлюсь *, но не сообщает, когда это безопасно. По сути, я хочу удалить out, если будет выпущено writer.

Может ли это быть достигнуто с помощью средства удаления буста? Идеи?

Ответы [ 2 ]

1 голос
/ 20 сентября 2010

Вы можете попытаться создать выходной поток в стеке в области, которая гарантированно будет жить дольше, чем любая ссылка на writer. Это зависит от вашей архитектуры, возможно ли это (хотя я бы сказал, что в хорошей архитектуре это должно быть).

Если у вас есть возможность договориться с разработчиком библиотеки (как вы упомянули в своем комментарии), попросите его / ее взять аргумент в качестве ссылки, если этого достаточно. shared_ptr следует использовать только в том случае, если право собственности на объект действительно является общим.

1 голос
/ 20 сентября 2010

Я не верю, что вы можете сделать это напрямую с помощью shared_ptr API.

Если Lib :: SomeClass является интерфейсом / абстрактным базовым классом, вы можете использовать Decorator . Идея состояла бы в том, чтобы определить класс, подклассы которого Lib::SomeClass, содержат shared_ptr<Lib::SomeClass> и std::ofstream*, и все методы которого перенаправляются в соответствующий метод содержащегося shared_ptr. Деструктор декоратора, однако, удалит содержащийся ofstream (или вы можете сохранить его в каком-то контейнере RAII, например scoped_ptr). Так что это будет экземпляр Decorator, который вы передали в appendWriter. Вот эскиз:

class SomeClassDecorator : public Lib::SomeClass
{
  public:
    SomeClassDecorator(shared_ptr<Lib::SomeClass> p, std::ofstream* stream)
      : p_(p), stream_(stream)
    {}

    virtual int MethodOfSomeClass(int x) {
        return p_->MethodOfSomeClass(x);
    }

  private:
    shared_ptr<Lib::SomeClass> p_;
    scoped_ptr<std::ofstream> stream_;
};

std::ofstream* out = new std::ofstream(); 
...
shared_ptr<Lib::SomeClass> writer = Library.createWriter(out);
shared_ptr<Lib::SomeClass> wrapper(new SomeClassDecorator(writer, out));

Library.appendWriter(wrapper);
...