在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)
这很好,只要我不知道。当我在python中删除a时,我在C ++的“ A”中创建的shared_ptr mb将尝试破坏B对象,该对象由Python管理并崩溃。因此,我的问题是C ++中是否存在一些不会从原始指针获取所有权的智能指针? weak_ptr无法正常工作,因为我仍然必须创建一个shared_ptr。
答案 0 :(得分:1)
Pybind11在幕后使用唯一的指针来管理C ++对象,因为它认为C ++对象拥有该对象,并且每当Python包装对象被释放时,都应释放该对象。但是,您正在与C ++代码库的其他部分共享此指针。这样,您需要使用B类的Python包装器来使用共享指针管理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