我为第三方库创建了绑定对象的所有权,因此我尝试使用FAQ中记录的auto_ptr。
这是我已经包装过的两个课程的一个例子:
typedef std::auto_ptr<Panel> PanelAutoPtr;
class NewPanelCallback {
public:
NewPanelCallback(object c) { callable = c; }
PanelAutoPtr operator() (wxWindow* parent) {
object result = callable(boost::ref(parent));
return extract<PanelAutoPtr>(result);
}
private:
object callable;
};
void Factory_register_method(Factory* f,
const wxString& id,
boost::python::object callable)
{
f->registerFactoryMethod(id, NewPanelCallback(callable));
}
class_<Factory, boost::noncopyable>("Factory", no_init)
.def("get", &Factory::get, return_value_policy<reference_existing_object>());
.def("register", &Factory_register_method);
class_<Panel, std::auto_ptr<Panel>, bases<wxWindow>, boost::noncopyable)
("Panel", init<wxWindow*, int, const wxString&>()>;
我的应用程序允许插件开发人员将Python函数注册为用于创建窗口小部件的工厂方法。一个例子:
class MyPanel(shell.Panel):
def __init__(self, parent, id, name):
super().__init__(parent, id, name)
def create_panel(parent):
return MyPanel(parent, -1, "Test")
shell.Factory.get().register("some_panel", create_panel)
现在,我的问题是当我的程序调用NewPanelCallback仿函数(在C ++中)时,面板对象在调用操作符返回之前被删除!它就像提取函数调用一样不会从结果对象中获取指针的所有权。
void create_a_panel(wxFrame* frm, NewPanelCallback& cb) {
PanelAutoPtr p = cb(frm);
frm->Add(p.get());
p.release();
}
任何提示?
我最后通过不使用&#34; extract&#34;来解决这个问题。这是我的新NewPanelCallback():
class NewPanelItemCallback {
public:
NewPanelItemCallback(object c) { callable = c; }
PanelAutoPtr operator() (wxWindow* parent) {
return call<Shell::PanelAutoPtr>(callable.ptr(), boost::ref(parent));
}
private:
object callable;
};
我不确定为什么会这样,而另一种方式则不然。对此有任何意见将不胜感激。
答案 0 :(得分:0)
不要使用auto_ptr - 它是邪恶的并且已弃用。将其替换为unique_ptr或shared_ptr。具体来说,auto_ptr更加急于通过无意中将所有权转移到temps来删除其有效负载,因为它缺少r值复制并且移动了unique_ptr和shared_ptr现在具有的语义。
答案 1 :(得分:0)
我找到了解决方案。我编辑了这个问题以包含答案。
答案 2 :(得分:0)
Boost支持movable
语义和unique_ptr
since v.1.55
但在我的项目中,我使用了以前的版本并制作了这样简单的包装器:
class_<unique_ptr<HierarchyT>, noncopyable>(typpedName<LinksT>("hierarchy", false)
, "hierarchy holder")
.def("__call__", &unique_ptr<HierarchyT>::get,
return_internal_reference<>(),
"get holding hierarchy")
.def("reset", &unique_ptr<HierarchyT>::reset,
"reset holding hierarhy")
;
创建unique_ptr<HierarchyT>
并将其传递给通过引用接受它的函数。 Python代码:
hier = mc.shierarchy()
mc.clusterize(hier, nds)
其中C ++函数是float clusterize(unique_ptr<HierarchyT>& hier,...)
然后使用Python访问结果:output(hier(), nds)
。
保持简单: - )