Ton*_*Big 5 c++ abstract-class shared-ptr boost-python
我们小组正在使用C++开发一个数字框架.我们现在想要将我们框架的基本部分包装在Python中.我们选择的武器是Boost.Python,因为我们已经将Boost用于其他目的.我们只使用smart_ptrs来支持多态性.以下代码段是我们如何应用策略模式的简单示例:
#include <boost/shared_ptr.hpp>
struct AbsStrategy
{
virtual std::string talk( ) = 0;
};
typedef boost::shared_ptr<AbsStrategy> StrategyPtr;
struct Foo : AbsStrategy
{
std::string talk( )
{
return "I am a Foo!";
}
};
struct Bar : AbsStrategy
{
std::string talk( )
{
return "I am a Bar!";
}
};
struct Client
{
Client( StrategyPtr strategy ) :
myStrategy( strategy )
{
}
bool checkStrategy( StrategyPtr strategy )
{
return ( strategy == myStrategy );
}
StrategyPtr myStrategy;
};
Run Code Online (Sandbox Code Playgroud)
如果我像这样用Boost.Python包装整个东西
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE( BoostPython )
{
class_<Foo>( "Foo" )
.def( "talk", &Foo::talk );
class_<Bar>( "Bar" )
.def( "talk", &Bar::talk );
class_<Client>( "Client", init<StrategyPtr>( ) )
.def( "checkStrategy", &Client::checkStrategy );
}
Run Code Online (Sandbox Code Playgroud)
编译期间会弹出以下警告
C:/boost/include/boost-1_51/boost/python/object/instance.hpp:14:36: warning: type attributes ignored after type is already defined [-Wattributes]
Run Code Online (Sandbox Code Playgroud)
当我尝试在python中使用包装器时,我收到以下错误
>>> from BoostPython import *
>>> foo = Foo()
>>> bar = Bar()
>>> client = Client(foo)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Tree.__init__(Tree, Foo)
did not match C++ signature:
__init__(_object*, boost::shared_ptr<AbsStrategy>)
>>> client = Client(bar)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Tree.__init__(Tree, Bar)
did not match C++ signature:
__init__(_object*, boost::shared_ptr<AbsStrategy>)
Run Code Online (Sandbox Code Playgroud)
在不改变我们的框架的情况下,让整个事情发挥作用缺少什么?包装纸当然可以自由调整.
好吧,我找到了解决方案。必须implicitly_convertible
在模块声明中使用,如下所示。
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE( BoostPython )
{
class_<Foo>( "Foo" )
.def( "talk", &Foo::talk );
class_<Bar>( "Bar" )
.def( "talk", &Bar::talk );
class_<Client>( "Client", init<StrategyPtr>( ) )
.def( "checkStrategy", &Client::checkStrategy );
implicitly_convertible<boost::shared_ptr<Foo> , StrategyPtr>();
implicitly_convertible<boost::shared_ptr<Bar> , StrategyPtr>();
}
Run Code Online (Sandbox Code Playgroud)