Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Cython中的继承和std::shared_ptr 假设我在>文件中有C++继承的简单例子.h : 类基{}; 派生类:公共基{};_Python_C++_Inheritance_Cython_Shared Ptr - Fatal编程技术网

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)
...