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.
In der Tat, ein virtueller d'tor war, was ich vermisst hatte. – shoosh
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