Python多态性。下注问题 我有C++中的基类列表,我想用Python访问它们的派生类的列表。
在Boost.Python中是否有一种内置方法来满足这一需求 我举了一个例子来说明我面临的问题:Python多态性。下注问题 我有C++中的基类列表,我想用Python访问它们的派生类的列表。,python,c++,boost,Python,C++,Boost,在Boost.Python中是否有一种内置方法来满足这一需求 我举了一个例子来说明我面临的问题: // ------------------------------- Code ----------------------------------// #include<memory> #include<iostream> #include<vector> namespace boost { template<class T> T* get_poin
// ------------------------------- Code ----------------------------------//
#include<memory>
#include<iostream>
#include<vector>
namespace boost { template<class T> T* get_pointer(std::shared_ptr<T>& p){ return p.get(); }}
struct Vehicle{ virtual ~Vehicle(){} friend bool operator==(const Vehicle& lhs, const Vehicle& rhs) { return true; }};
struct Boat: public Vehicle{
virtual ~Boat(){}
friend bool operator==(const Boat& lhs, const Boat& rhs) { return true; }
char const* testBoatSpecificMethod() { return "Floating."; }
};
struct Truck: public Vehicle{
virtual ~Truck(){}
friend bool operator==(const Truck& lhs, const Truck& rhs) { return true; }
char const* testTruckSpecificMethod() { return "Trucking."; }
};
class Garage
{
public:
Garage() {};
~Garage() {};
char const* test() { std::string temp = "Vehicle List Size: " + std::to_string(m_VehicleList.size()); return temp.c_str(); }
friend bool operator==(const Garage& lhs, const Garage& rhs) { return true; }
std::vector<std::shared_ptr<Vehicle>>& vehicleList() { return m_VehicleList; }
private:
std::vector<std::shared_ptr<Vehicle>> m_VehicleList;
};
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
BOOST_PYTHON_MODULE(garage_ext)
{
using namespace boost::python;
class_<Garage>("Garage")
.def("test", &Garage::test)
.def("vehicleList", &Garage::vehicleList, return_internal_reference<1>());
class_<Vehicle,std::shared_ptr<Vehicle>>("Vehicle");
class_<Boat,std::shared_ptr<Boat>,bases<Vehicle>>("Boat")
.def("testBoatSpecificMethod", &Boat::testBoatSpecificMethod);
class_<Truck,std::shared_ptr<Truck>,bases<Vehicle>>("Truck")
.def("testTruckSpecificMethod", &Truck::testTruckSpecificMethod);
implicitly_convertible<std::shared_ptr<Boat>,std::shared_ptr<Vehicle>>();
implicitly_convertible<std::shared_ptr<Truck>,std::shared_ptr<Vehicle>>();
class_<std::vector<std::shared_ptr<Vehicle>> >("stl_vector_Vehicle")
.def(vector_indexing_suite<std::vector<std::shared_ptr<Vehicle>> >());
}
// --------------------------- Test Script -------------------------------//
import garage_ext
g = garage_ext.Garage()
l = g.vehicleList()
l.append(garage_ext.Boat())
print "Expecting a Boat object:"
print str(l[0])
print g.vehicleList()[0].testBoatSpecificMethod()
garage_ext.f2("Done.")
/------------------------------------代码----------------------------------//
#包括
#包括
#包括
命名空间boost{template T*get_指针(std::shared_ptr&p){return p.get();}
结构Vehicle{virtual~Vehicle(){}友元布尔运算符==(const Vehicle&lhs,const Vehicle&rhs){返回true;};
结构艇:公共车辆{
虚拟~Boat(){}
friend bool运算符==(const Boat&lhs、const Boat&rhs){return true;}
char const*testBoatSpecificMethod(){返回“Floating.”;}
};
结构卡车:公共车辆{
虚拟~Truck(){}
friend bool运算符==(常数卡车和左侧、常数卡车和右侧){return true;}
char const*testTruckSpecificMethod(){返回“Trucking.”;}
};
班级车库
{
公众:
车库{};
~Garage(){};
char const*test(){std::string temp=“车辆列表大小:”+std::to_string(m_VehicleList.Size());return temp.c_str();}
friend bool运算符==(const Garage&lhs、const Garage&rhs){return true;}
std::vector&vehicleList(){return m_vehicleList;}
私人:
std::矢量m_车辆列表;
};
#包括
#包括
BOOST_PYTHON_模块(车库扩展)
{
使用名称空间boost::python;
第二类(“车库”)
.def(“测试”和车库::测试)
.def(“车辆列表”和车库::车辆列表,返回内部参考();
第二类(“车辆”);
第二类(“船”)
.def(“TestBoatsSpecificMethod”和Boat::TestBoatsSpecificMethod);
第二类(“卡车”)
.def(“testTruckSpecificMethod”和卡车::testTruckSpecificMethod);
隐式可转换();
隐式可转换();
类别(“stl矢量车辆”)
.def(向量索引套件());
}
//------------------------------测试脚本-------------------------------//
导入车库扩展
g=车库\外部车库()
l=g.车辆列表()
l、 附加(车库外部船())
打印“预期船对象:”
打印str(l[0])
打印g.vehicleList()[0].testBoatSpecificMethod()
车库分机f2(“完成”)
//-------------------------------------输出---------------------------------//
期待一个船的对象
回溯(最近一次呼叫最后一次):
文件“test_garage.py”,第7行,在
打印g.vehicleList()[0].testBoatSpecificMethod()
AttributeError:“Vehicle”对象没有属性“TestBoatsSpecificMethod”
“Vehicle”对象没有属性“TestBoatsSpecificMethod”
在这里,我希望车辆是一个船的对象
如果没有内置或推荐/已知的Boost.Python方法来处理此问题,
我将尝试用get访问器返回boost::python::list,将派生的大多数类型存储在python list对象中,从而包装列表(在我的库中有很多包装工作要做)。通过调用重写的“getAsDerivedClass”方法获取派生的most类型。
我想避免这种情况。出于我们的设计和愿景价值/原因,我不喜欢向库中添加python使用特定的方法。另一个问题是,这种方式将引入大量额外的维护工作
编辑:
当我使用原始指针而不是智能指针时,我想要的工作正常。
因为我觉得很明显的原因,我不想用原始指针代替智能指针。
这确实让我松了一口气,因为知道我想要什么这个概念并不像我开始担心的那样牵强。(我仍在努力使它与智能指针一起工作。python对象需要一个转换器,手工编写转换器的工作量太大。)继承错误:你不能存储向量并期望它具有运行时多态性。这只是普通的C++,你需要存储向量或SypDypPTR等。@ JohnZwinck谢谢约翰,我把代码修好了。我错误地忘记了将列表作为共享指针的列表。通过Boost.Python转换代码,您可以注意到vector就是我们的意图。这个问题仍然存在,不幸的是,不仅仅是一般C++,正如你可以从我的描述中所看到的。现在看来,问题似乎是<>代码> BoAtActudio方法< /代码>等在基类中不存在为<代码>虚拟< /代码>方法。我认为,它们必须是……或者你的向量需要包含boost::python::objects或者其他一些会让生活变得更棘手的东西。是的,这就是我现在所处的位置。这就是为什么我提到使用boost::python::list包装列表,该列表存储派生的most类型。出于上述原因,这是不需要的,我正在尝试找出Boost.Python中是否没有内置的机制。注意,我调用了BoatSpecificMethod来证明我只想使用特定于派生类的方法,而不是作为虚拟方法存在于基中。