C ++ умный указатель на внешние управляемые (например, Python) ресурсы? - PullRequest
0 голосов
/ 15 декабря 2018

Есть ли в C ++ умный указатель на ресурс, управляемый другими?Я использую pybind11, чтобы обернуть код C ++ следующим образом.

    class B {};
    class A {
      public:
        // original C++ class interface
        A(std::shared_ptr<B> pb) : mb(pb){}
        // have to add this for pybind11, since pybind11 doesn't take shared_ptr as argument.
        A(B * pb):A(std::shared_ptr<B>(pb)){}
      private:
        std::shared_ptr<B> mb;
    }
    namespace py = pybind11;
    PYBIND11_MODULE(test, m)
    {
       py::class_<B>(m, "B")
       .def(py::init<>());

       py::class_<A>(m, "A")
       .def(py::init<B *>());
    }

Затем в python я буду использовать их следующим образом:

    b = B()
    a = A(b)

Это хорошо, пока я нетель а.Когда я делаю a в Python, mb shared_ptr, который я создал в C ++, 'A' будет пытаться уничтожить объект B, которым управляет Python, и аварийно завершить работу.Итак, мой вопрос: есть ли в C ++ какой-нибудь умный указатель, который не получает владения от необработанного указателя?weak_ptr не будет работать, потому что мне все равно придется создать shared_ptr.

1 Ответ

0 голосов
/ 15 декабря 2018

Pybind11 использует уникальный указатель за кулисами для управления объектом C ++, так как считает, что он владеет объектом, и должен освобождать объект всякий раз, когда освобождается объект-оболочка Python.Однако вы делитесь этим указателем с другими частями базы кода C ++.Таким образом, вам нужно сделать обертку Python класса B для управления экземпляром B с помощью общего указателя.Вы можете сделать это с помощью шаблона class_.например,

PYBIND11_MODULE(test, m)
{
   py::class_<B, std::shared_ptr<B> >(m, "B")
   .def(py::init<>());

   py::class_<A>(m, "A")
   .def(py::init<std::shared_ptr<B> >());
}

https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html#std-shared-ptr

...