在绑定派生 class 时,我还必须将所有父 class 绑定到根 class 吗?

In binding a derived class must I also bind all parent classes to the root class?

判断对错

To bind a derived class in a C++ class hierarchy one must also bind all the parent classes on up to the root class.

我希望在我刚刚开始的项目中绑定一堆自定义数据类型,并希望确定所涉及工作的范围。我希望绑定一个 class,它是远离根类型的 3 个派生级别。

对于何时还必须绑定父 classes 才能成功绑定子 classes,是否有任何经验法则?


让我们考虑一个简单的例子:

#include <string>

class Parent
{
public:
    Parent() { m_name = "Parent"; }

    std::string foo() { return m_name + "::foo"; }

    virtual std::string bar() { return m_name + "::bar"; }

protected:
    std::string m_name;
};

class Derived : public Parent
{
public:

    Derived() { m_name = "Derived"; }

    std::string bar() override { return m_name + "::bar (override)"; }
};

您可以按照您描述的方式绑定:绑定父级,派生的 class 将受益于所有派生的方法(您甚至不必绑定 override):

#include <pybind11/pybind11.h>

namespace py = pybind11;

PYBIND11_MODULE(example, m)
{
    py::class_<Parent>(m, "Parent")
        .def(py::init<>(), "Constructor description")
        .def("foo", &Parent::foo, "Function description")
        .def("bar", &Parent::bar, "Function description")
        .def("__repr__", [](const Parent&) { return "<Parent>"; });

    py::class_<Derived, Parent>(m, "Derived")
        .def(py::init<>(), "Constructor description")
        .def("__repr__", [](const Derived&) { return "<Derived>"; });
}

确实

import example

p = example.Parent()
print(p.foo())
print(p.bar())

d = example.Derived()
print(d.foo())
print(d.bar())

将打印

Parent::foo
Parent::bar
Derived::foo
Derived::bar (override)

但是,如果您只想绑定一个派生的 class(您不关心父级,也不关心任何其他派生的 classes),您也可以 just 绑定您关心的派生 class,而无需指定父级:

#include <pybind11/pybind11.h>

namespace py = pybind11;

PYBIND11_MODULE(example, m)
{
    py::class_<Derived>(m, "Derived")
        .def(py::init<>(), "Constructor description")
        .def("foo", &Derived::foo, "Function description")
        .def("bar", &Derived::bar, "Function description")
        .def("__repr__", [](const Derived&) { return "<Derived>"; });
}

确实

import example

d = example.Derived()
print(d.foo())
print(d.bar())

打印

Derived::foo
Derived::bar (override)

参考the docs