2012-05-14 17 views
5

Ich habe eine Methode (oder Funktion), die einen Verweis auf eine Liste von polymorphen Objekten zurückgibt:Boost Python: polymorpher Container?

class A { 

}; 
class B : public A { 

}; 


std::list<boost::shared_ptr<A> >& getList(); 

Wie aussetzen ich eine solche Funktion in boost :: Python, so dass, wenn sie auf der Liste in Python iterieren, Ich würde die verschiedenen Arten von A s und B s sehen?

Antwort

4

Stellen Sie zunächst sicher, dass Ihre Klassen tatsächlich polymorph sind (d. H. Sie haben mindestens eine virtuelle Funktion oder einen virtuellen Destruktor). Dein Beispiel oben funktioniert nicht, obwohl ich mir sicher bin, dass es dein echter Anwendungsfall ist. Ohne das würde keiner der RTTI-basierten Polymorphie-Werkzeuge von Boost.Python funktionieren.

Dann, wenn Sie beide Klassen mit Boost.Python ausgesetzt haben und registriert shared_ptr Konverter für sie:

#include <boost/python.hpp> 

namespace bp = boost::python; 

BOOST_PYTHON_MODULE(example) { 
    bp::class_<A >("A"); 
    bp::register_ptr_to_python< boost::shared_ptr<A> >(); 
    bp::class_< B, bp::bases<A> >("B"); 
    bp::register_ptr_to_python< boost::shared_ptr<B> >(); 
} 

... das ist alles, was Sie tun müssen, um sicherzustellen, dass Python machen sieht immer nur die meist abgeleiteter Typ. Es ist nicht nötig, etwas Besonderes zu tun, um sicherzustellen, dass A wenn möglich in B umgewandelt wird.

Das lässt immer noch die Frage, wie eine Funktion umbrochen wird, die einen Container zurückgibt. Die einfachste ist wahrscheinlich die Indizierung Suite mit Boost.Python enthalten zu verwenden:

http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/indexing.html

Es gibt andere Optionen rund um die Web-Floating (einschließlich einer „Version 2“ der Indizierung Suite, die besser in vielerlei Hinsicht, aber ist nicht in Boost.Python enthalten), aber für einfache Probleme ist dies wahrscheinlich die bequemste.

+0

In der Tat, ein virtueller d'tor war, was ich vermisst hatte. – shoosh

+0

In Bezug auf die Frage, wie Sie eine Funktion umbrechen, die einen Container zurückgibt: Diese Methode funktioniert auch direkt mit Methoden zum Aussetzen, die eine boost :: python :: list zurückgeben. I.e. durch Anhängen von boost :: shared_ptr an polymorphe Python-Elemente an die Liste. Die Dereferenzierung der Zeiger beim Zugriff auf die Liste zur Laufzeit wird dann implizit wie beschrieben durchgeführt (wenn die Definitionen von register_ptr_to_python <> existieren). – StefanQ

Verwandte Themen