[C++-sig] shared_ptr, abstract classes and inheritance

Tobias Kräntzer info at tobias-kraentzer.de
Tue Oct 24 21:24:44 CEST 2006


hello altogether,

i have a problem using boost::python and boost::shared_ptr with abstract 
classes and inheritance.

i am using a structure of abstract classes as interface. the implementation is 
in derived classes of the base classes.

    class Base { /* ..pure virtual methods.. */ };
    class Derived : Base { /* ..pure virtual methods.. */ };

    class Base_impl : Base { /* ..implementation gose here.. */ };
    class Derived_impl : Derived { /* ..implementation gose here.. */ };

the object creation is handled with a factory which always returns a 
shared_ptr< Base >.

    shared_ptr< Base > factory( bool use_derived);

if the factory creates a derived class i want have access to that interface.

>>> base = factory( False )    # object of type Base
>>> derived = factory( True )  # object of type Derived

how can i handle this?

greetings,
. . . tobias



the complete code looks like this:

#include <string>
#include <boost/shared_ptr.hpp>

// Interface ///////////////////////////////

class Base
{
    public:
        typedef boost::shared_ptr< Base > Ptr;

        virtual std::string foo() const = 0;
};

class Derived : public Base
{
    public:
        typedef boost::shared_ptr< Derived > Ptr;

        virtual std::string bar() const = 0;
};

Base::Ptr factory( bool use_derived );

// Implementation //////////////////////////

class Base_impl : public Base
{
    friend Base::Ptr factory( bool use_derived );

    public:
        std::string foo() const { return( "Base foo" ); };
};

class Derived_impl : public Derived
{
    friend Base::Ptr factory( bool use_derived );

    public:
         std::string foo() const { return( "Derived foo" ); };
         std::string bar() const { return( "Derived bar" ); };
};

// Factory /////////////////////////////////

Base::Ptr factory( bool use_derived )
{
    if ( !use_derived )
    {
        Base::Ptr pt( new Base_impl() );
        return( pt );
    }
    else
    {
        Derived::Ptr pt( new Derived_impl() );
        return( pt );
    };
};

// Python //////////////////////////////////

#include <boost/python.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE( test )
{
    class_< Base, Base::Ptr, boost::noncopyable >( "Base", no_init )
        .def( "foo", &Base::foo )
        ;

    class_< Derived, Derived::Ptr, bases< Base >, boost::noncopyable 
>( "Derived", no_init )
        .def( "foo", &Derived::foo )
        .def( "bar", &Derived::bar )
        ;

    def( "factory", &factory );
};



More information about the Cplusplus-sig mailing list