说到boost::shared_ptr
,Boost.Python 通常会提供所需的功能。to_python
在这种特殊情况下,只要模块声明定义了Base
由 持有的boost::shared_ptr<Base>
,并且 Boost.Python 被告知A
继承自,就不需要显式提供自定义转换器Base
。
BOOST_PYTHON_MODULE(example) {
using namespace boost::python;
class_<Base, boost::shared_ptr<Base>,
boost::noncopyable>("Base", no_init);
class_<A, bases<Base>,
boost::noncopyable>("A", no_init);
def("factory", &factory);
def("consumer", &consumer);
}
Boost.Python 目前不支持自定义左值转换器,因为它需要更改核心库。因此,该consumer
函数需要接受boost:shared_ptr<A>
按值或按常量引用。以下任何一个签名都应该有效:
void consumer(boost::shared_ptr<A> a)
void consumer(const boost::shared_ptr<A>& a)
这是一个完整的例子:
#include <boost/python.hpp>
#include <boost/make_shared.hpp>
class Base
{
public:
virtual ~Base() {}
};
class A
: public Base
{
public:
A(int value) : value_(value) {}
int value() { return value_; };
private:
int value_;
};
boost::shared_ptr<Base> factory()
{
return boost::make_shared<A>(42);
}
void consumer(const boost::shared_ptr<A>& a)
{
std::cout << "The value of object is " << a->value() << std::endl;
}
BOOST_PYTHON_MODULE(example) {
using namespace boost::python;
class_<Base, boost::shared_ptr<Base>,
boost::noncopyable>("Base", no_init);
class_<A, bases<Base>,
boost::noncopyable>("A", no_init);
def("factory", &factory);
def("consumer", &consumer);
}
以及用法:
>>> from example import *
>>> x = factory()
>>> type(x)
<class 'example.A'>
>>> consumer(x)
The value of object is 42
>>>
由于指定的模块声明Base
是 的基类A
,Boost.Python 能够解析从factory()
to返回的类型example.A
。