具有pybind的多态类 我想用pyBIN将多态C++类层次结构封装到Python。
具有pybind的多态类 我想用pyBIN将多态C++类层次结构封装到Python。,python,c++,pybind11,Python,C++,Pybind11,我的意图是Python类继承了Python代码中的包C++类,并覆盖了一些函数。在下面的例子中,有一个Python类猫,它继承了C++类的动物和oviWrand函数GO()。这正在工作,print(test.call\u go(c)按预期打印“喵!喵!喵!” Python类贝洛继承C++类狗,应该覆盖函数BARK()和GO()。但是它不起作用。BARK()和GO()是否被类贝洛重写。< /P> print(test.call_go(b))print“呜!呜!呜!”。我希望是“grrrr!grr
我的意图是Python类继承了Python代码中的包C++类,并覆盖了一些函数。在下面的例子中,有一个Python类猫,它继承了C++类的动物和oviWrand函数GO()。这正在工作,
print(test.call\u go(c)
按预期打印“喵!喵!喵!”
Python类贝洛继承C++类狗,应该覆盖函数BARK()和GO()。但是它不起作用。BARK()和GO()是否被类贝洛重写。< /P>
print(test.call_go(b))
print“呜!呜!呜!”。我希望是“grrrr!grrrr!grrrr!”
及
print(test.call_bark(b))
prints“woof!”。我希望是“grrrr!”
pybind Inhination似乎只适用于一个多态级别。我天真的期望是,它与CPP类似或类似。我只能从直接继承的类重写函数
我希望你能给我一个提示让它工作或者告诉我为什么它不能工作。提前谢谢你
我尝试了以下修改:
- 将PyDog用作蹦床而不是动物--
py::class_m(“狗”)
- 在python代码中调用print(test.call_go(d))会导致一个错误,因为d不再是Animal类型。我不知道为什么,因为PyDog继承自Animal。函数bark()按预期过度编写
- 若python类Bello继承自test.Animal而非test.Dog,那个么函数go将按预期被覆盖
你有没有发现答案?我很好奇你有没有发现答案?我也很好奇
class Animal {
public:
virtual std::string go(int n_times) = 0;
virtual std::string name() { return "unknown"; }
};
class Dog : public Animal {
public:
std::string go(int n_times) override {
std::string result;
for (int i=0; i<n_times; ++i)
result += bark() + " ";
return result;
}
virtual std::string name() { return "Dog"; }
virtual std::string bark() { return "woof!"; }
};
class PyAnimal : public Animal {
public:
using Animal::Animal; // Inherit constructors
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, Animal, go, n_times); }
std::string name() override { PYBIND11_OVERLOAD(std::string, Animal, name, ); }
};
class PyDog : public Dog {
public:
using Dog::Dog; // Inherit constructors
std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, Dog, go, n_times); }
std::string name() override { PYBIND11_OVERLOAD(std::string, Dog, name, ); }
std::string bark() override { PYBIND11_OVERLOAD(std::string, Dog, bark, ); }
};
std::string call_go(Animal *animal) {
return animal->go(3);
}
std::string call_bark(Dog *dog) {
return dog->bark();
}
PYBIND11_MODULE(_MyTest, m)
{
py::class_<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal")
.def(py::init<>())
.def("go", &Animal::go);
py::class_<Dog, Animal>(m, "Dog")
.def(py::init<>())
.def("go", &Dog::go)
.def("bark", &Dog::bark);
m.def("call_go", &call_go);
m.def("call_bark", &call_bark);
}
#!/usr/bin/env python3
import sys
from ATOM import _MyTest as test
def main(argv=None):
print("check Dog")
d = test.Dog()
print(test.call_go(d))
print(test.call_bark(d))
class Cat(test.Animal):
def go(self, n_times):
return "meow! " * n_times
print("check Cat")
c = Cat()
print(test.call_go(c))
print("check Bello")
class Bello(test.Dog):
def go(self, n_times):
return "grrrr! " * n_times
def bark(self):
return "grrrr! "
b = Bello()
print(test.call_go(b))
print(test.call_bark(b))
print(b.go(3))
print(b.bark())
if __name__ == "__main__":
sys.exit(main())