用于声明具有别名的类层次结构的Cython语法
Cython syntax for declaring class hierarchies that have aliases
这里有一个抽象基类和一个具体子类,我想通过Cython:将其公开给Python
class NodeDistance {
protected:
const Graph& G;
public:
NodeDistance(const Graph& G);
virtual ~NodeDistance();
virtual void preprocess() = 0;
virtual double distance(node u, node v) = 0;
};
class NeighborhoodDistance: public NetworKit::NodeDistance {
public:
NeighborhoodDistance(const Graph& G);
virtual ~NeighborhoodDistance();
virtual void preprocess();
virtual double distance(node u, node v);
};
这是我第一次尝试为Cython声明类的接口。为了避免cppclass
es和Python包装类之间的命名冲突,我将每个Class
声明为_Class
,然后声明其正确名称"Namespace::Class"
。
cdef extern from "../cpp/distmeasures/NodeDistance.h":
cdef cppclass _NodeDistance "NetworKit::NodeDistance":
_NodeDistance(_Graph G) except +
void preprocess() except +
double distance(node, node) except +
cdef extern from "../cpp/distmeasures/NeighborhoodDistance.h":
cdef cppclass _NeighborhoodDistance(_NodeDistance) "NetworKit::NeighborhoodDistance":
_NeighborhoodDistance(_Graph G) except +
void preprocess() except +
double distance(node, node) except +
但现在我在试图表达_NeighborhoodDistance
是_NodeDistance
的子类时遇到了语法错误。我做错了什么?
Error compiling Cython file:
------------------------------------------------------------
...
void preprocess() except +
double distance(node, node) except +
cdef extern from "../cpp/distmeasures/NeighborhoodDistance.h":
cdef cppclass _NeighborhoodDistance(_NodeDistance) "NetworKit::NeighborhoodDistance":
^
------------------------------------------------------------
_NetworKit.pyx:1698:52: Syntax error in C++ class definition
我认为您甚至无法在Cython 0.20.1中表达基类和重命名的组合。您可以不重命名类,而是在cdef extern from
:中指定名称空间
# C++ classes shown at the end
cdef extern from "example.hpp" namespace "example":
cdef cppclass Base:
void some_method() except +
cdef cppclass Derived(Base):
void some_method() except +
或不指定继承:
cdef extern from "example.hpp" namespace "example":
cdef cppclass Base "example::Base":
void some_method() except +
cdef cppclass Derived "example::Derived":
void some_method() except +
不管怎样,Cython似乎并没有完全理解C++继承,您需要一个显式的强制转换:
def test():
cdef Derived d
cdef Base *p = <Base *>&d
p.some_method()
这很难看,因为在C++中,强制转换有效地关闭了类型检查,但要小心,它可以安全地使用。(在其他情况下,Cython的类型检查需要C/C++中不需要的类型转换,这是非常不幸的。(
作为参考,以下是我使用的类:
// example.hpp
#include <cstdio>
namespace example {
struct Base {
virtual void some_method() = 0;
virtual ~Base() = 0;
};
struct Derived {
virtual void some_method()
{
std::puts("Hello!");
}
~Derived()
{
}
};
}
相关文章:
- 如何重构类层次结构以避免菱形问题
- C++ 中模板化类型的类层次结构
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 继承层次结构并将元素添加到向量
- C++ 类层次结构中的"对齐"是什么意思?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 类层次结构中的运算符重载
- 如何在层次结构中实现运算符使用?
- 反向层次结构中的可变参数模板参数
- 如何在继承层次结构中调用具有默认参数的构造函数?
- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++继承层次结构时提取实现者
- 在C++中将类实例添加到对象层次结构中的问题
- 确定大层次结构中基本指针的实际类型,无需dynamic_cast
- 在继承层次结构中复制和移动
- 模板冲突的类型-但类型应该是相同的cfr类层次结构
- 删除父/子窗口层次结构的最佳方法
- 是否可以使一个类成为两个不同层次结构的子类?
- 编写C 简化具有复杂层次结构的C 类的包装器,以便Cython可以称呼它
- 用于声明具有别名的类层次结构的Cython语法