Boost logo

Boost Users :

Subject: Re: [Boost-users] Boost.Python: Polymorphism downcasting
From: Christoff Kok (christoff.kok_at_[hidden])
Date: 2014-10-16 00:55:59


UPDATE:

I erroneously created the example without the vehicle list being a list of
smart pointer. I get the exact same output with the list being a list of
smart pointers.

When it is a list of raw pointers, it works as desired.
What can I change to make the list of smart pointers behave like raw
pointers? Making it boost::shared_ptrs instead of std::shared_ptrs makes no
difference.

Kind Regards,
Christoff

On 13 October 2014 16:30, Christoff Kok <christoff.kok_at_[hidden]>
wrote:

> Hi,
>
> I have a list of base classes in C++, I want to access them in Python as a
> list of their derived most classes.
>
> Is there a build in means to cater for this in Boost.Python?
>
> I've made an example the problem I ma facing:
>
> // ------------------------------- 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<Vehicle>& vehicleList() { return m_VehicleList; }
> private:
> std::vector<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<Vehicle> >("stl_vector_Vehicle")
> .def(vector_indexing_suite<std::vector<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.")
>
> // ------------------------------ Output
> ---------------------------------//
> Expecting a Boat object
> <garage_ext.Vehicle object at 0x7fb17a3bfb50>
> Traceback (most recent call last):
> File "test_garage.py", line 7, in <module>
> print g.vehicleList()[0].testBoatSpecificMethod()
> AttributeError: *'Vehicle' object has no attribute
> 'testBoatSpecificMethod'*
>
> *'Vehicle' object has no attribute 'testBoatSpecificMethod'*
> Here I want Vehicle to be a Boat object.
>
> If there is not a build in or recommended/known Boost.Python means to
> handle this problem,
> I'm thinking of wrapping the list (Lots of accessors to be wrapped in my
> library.) with a get accessor returning a boost::python::list, storing the
> derived most types. Getting the derived most type possibly by calling
> overriden 'getAsDerivedClass' method. I would like to avoid this. I dislike
> having to add python usage specific methods to the library, for our design
> and vision values / reasons.
>
> Kind Regards,
> Christoff
>

-- 
Christoff Kok
Software Engineer
Ex Mente
http://www.ex-mente.co.za
christoff.kok_at_[hidden]
PO Box 10214
Centurion
0046
South Africa
tel: +27 12 743 6993
tel: +27 12 654 8198
fax: +27 85 150 1341


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net