Python Cython中的继承和std::shared_ptr 假设我在>文件中有C++继承的简单例子.h : 类基{}; 派生类:公共基{};
然后,编译以下代码;也就是说,我可以将Python Cython中的继承和std::shared_ptr 假设我在>文件中有C++继承的简单例子.h : 类基{}; 派生类:公共基{};,python,c++,inheritance,cython,shared-ptr,Python,C++,Inheritance,Cython,Shared Ptr,然后,编译以下代码;也就是说,我可以将std::shared_ptr分配给std::shared_ptr: Derived*foo=new-Derived(); std::shared_ptr shared_foo=std::make_shared(*foo); std::shared_ptr bar=shared_foo; 假设我已经将类型添加到decl.pxd: “file.h”中的cdef外部程序: cdef cppclass基类: 通过 cdef cppclass派生(基): 通过
std::shared_ptr
分配给std::shared_ptr
:
Derived*foo=new-Derived();
std::shared_ptr shared_foo=std::make_shared(*foo);
std::shared_ptr bar=shared_foo;
假设我已经将类型添加到decl.pxd
:
“file.h”中的cdef外部程序:
cdef cppclass基类:
通过
cdef cppclass派生(基):
通过
那么,我要做的就是模仿Cython上面的C++赋值在<代码>文件中。
cimport decl
从libcpp.memory cimport使共享,共享
def do_stuff():
cdef decl.Derived*foo=new decl.Derived()
cdef shared_ptr[decl.Derived]shared_foo=make_shared[decl.Derived](foo)
cdef shared_ptr[decl.Base]bar=shared_foo
与C++情况不同,现在失败了以下错误(使用Cython 3.0A6):
我应该期待这种行为吗?有没有什么方法可以模仿C++实例对Cython的作用?编辑:参考下面对已接受答案的评论,相关功能已添加到Cython中,并从3.0a7版开始提供。我没有尝试过Cyton,但
std::shared\u ptr
具有静态转换功能std::static\u pointer\u cast
。我想这会管用的
std::shared_ptr<Base> bar = std::static_pointer_cast<Base>(shared_foo);
作为旁注 您创建
shared\u foo
的方式可能不是您想要的。这里首先创建一个动态分配的派生。然后,您将创建一个新的动态分配的共享派生文件,它是原始文件的副本
// this allocates one Derived
Derived* foo = new Derived();
// This allocates a new copy, it does not take ownership of foo
std::shared_ptr<Derived> shared_foo = std::make_shared<Derived>(*foo);
//这将分配一个派生的
派生*foo=新派生();
//这将分配一个新副本,但它不拥有foo的所有权
std::shared_ptr shared_foo=std::make_shared(*foo);
您可能想要的是:
Derived* foo = new Derived();
std::shared_ptr<Derived> shared_foo(foo); // This now takes ownership of foo
Derived*foo=new-Derived();
std::shared_ptr shared_foo(foo);//现在它拥有了foo的所有权
或者只是:
// This makes a default constructed shared Derived
auto shared_foo = std::make_shared<Derived>();
//这将使默认构造的共享
自动共享_foo=std::使_共享();
它应该适用于Cython>=3.0,因为@fuglede解决了下面描述的问题(CythonGood point仍然存在)。据我(有限)所知,Cython中没有与shared_foo(foo);
等价的东西,这意味着生成的代码可能会遇到相同的问题(?)你是对的,所以实际上,static\u pointer\u cast[decl.Base,decl.Derived](shared\u foo)
似乎做了我想做的事情!相关声明已经添加,并且应该在将来某个时候可以使用。@fuglede感谢您的PR!对不起,我弄乱了签名-不知道它是如何发生的,以及为什么它与cython一起工作……当然很奇怪,它是以任何方式工作的。无论如何,PR已经合并,并且Cython 3.0a7中提供了功能,因此感谢您的回答和提示!
Derived* foo = new Derived();
std::shared_ptr<Derived> shared_foo(foo); // This now takes ownership of foo
// This makes a default constructed shared Derived
auto shared_foo = std::make_shared<Derived>();
cdef extern from "<memory>" namespace "std" nogil:
cdef cppclass shared_ptr[T]:
...
shared_ptr[T]& operator=[Y](const shared_ptr[Y]& ptr)
#shared_ptr[Y](shared_ptr[Y]&) isn't accepted
...
cdef shared_ptr[decl.Base] bar = shared_foo
std::shared_ptr<Base> __pyx_v_bar;
...
__pyx_v_bar = __pyx_v_shared_foo;
std::shared_ptr<Base> __pyx_v_bar = __pyx_v_shared_foo;
%%cython
...
cdef extern from *:
"""
template<typename T1, typename T2>
void assign_shared_ptr(std::shared_ptr<T1>& lhs, const std::shared_ptr<T2>& rhs){
lhs = rhs;
}
"""
void assign_shared_ptr[T1, T2](shared_ptr[T1]& lhs, shared_ptr[T2]& rhs)
...
cdef shared_ptr[Derived] shared_foo
# cdef shared_ptr[decl.Base] bar = shared_foo
# must be replaced through:
cdef shared_ptr[Base] bar
assign_shared_ptr(bar, shared_foo)
...