如何通过暴露抽象类来从抽象类(接口类)访问python中的派生类,而不暴露派生类。我不想暴露python的派生类。有没有办法可以通过抽象类访问派生类?示例代码是:
Base.h
class Base
{
public:
virtual void Set(const std::vector<std::string>& AllParameters) = 0;
};
struct BaseWrap : Base, wrapper<Base>
{
void Set(const std::vector<std::string>& AllParameters)
{
this->get_override("Set")(AllParameters);
}
}
Base.cpp
BOOST_PYTHON_MODULE(Example)
{
class_<Basewrapper , boost::noncopyable> ("Base")
.def("Set",pure_virtual(&Base::Set))
;
}
Derived.h
class Derived : public Base
{
public:
void Set(const std::vector<std::string>& AllParameters);
int test(int a, int b);
};
Derived.cpp
void Derived::Set(const std::vector<std::string>& AllParameters)
{
//some code here
}
void Derived:: test(int a , int b)
{
return a+b;
}
答案 0 :(得分:4)
据我所知,没有暴露类就无法访问类。 Boost.Python需要公开静态类型。但是,只要静态类型已暴露,就可以获得虚拟函数解析到其动态类型尚未通过Boost.Python公开的实例。例如,如果:
Base
和Base::foo()
暴露于Boost.Python Derived
继承自Base
Derived
会覆盖Base::foo()
然后,Derived
实例的句柄可以通过Boost.Python传递,其静态类型为Base*
或Base&
,并在生成的Python上调用foo()
对象将解析为Derived::foo()
。
这是一个完整的代码示例:
#include <boost/python.hpp>
struct Base
{
virtual int foo() = 0;
virtual ~Base() {}
};
struct Derived
: public Base
{
int foo()
{
return 42;
}
};
/// @brief Factory method to create Derived objects, but return as
/// Base*. If the instance was returned as a Derived*, then
/// Derived would need to be directly exposed to Boost.Python.
Base* make_derived()
{
return new Derived;
}
namespace python = boost::python;
/// @brief Wrapper that will provide a non-abstract type for Base.
struct BaseWrap
: public Base, public python::wrapper<Base>
{
int foo()
{
return this->get_override("foo")();
}
};
BOOST_PYTHON_MODULE(example)
{
// Exposes BaseWrap in Python as Base. This also causes C++ Base to be
// indirectly exposed for conversions via Boost.Python's wrapper.
python::class_<BaseWrap, boost::noncopyable>("Base")
.def("foo", python::pure_virtual(&Base::foo))
;
// Make an instance of Derived, but return the instance as Base*. As
// Base is indirectly exposed via the wrapper, a handle to the object
// is passed through the Boost.Python layer.
python::def("make_derived", &make_derived,
python::return_value_policy<python::manage_new_object>());
}
交互式使用:
>>> import example
>>> d = example.make_derived()
>>> d.foo()
42
>>> class Spam(example.Base):
... def foo(self):
... return 101
...
>>> s = Spam()
>>> s.foo()
101