Dear all,

first of all thanks to Holger for pointing me to a workaround with the 
add_static_property problem!

Unfortunately, I already ran into the next problem, which seems very weird to 
me:

I have again my old friends Base and Derived, with the obvious inheritance 
(source file attached). Now, there is a third class, named "Third", which has 
as a data member a boost::shared_ptr<Base> which is initialized in the 
constructor. For this reason, the constructor takes such a pointer as an 
argument.

Now, the point where stuff goes wrong is this: the argument to the constructor 
has as a default value a NULL-boost::shared_ptr<Base>. The behavior now works 
as expected if the argument is provided in python:

>>> import testInheritance
>>> t = testInheritance.Third(testInheritance.Derived())
>>> t.get_base().name()
'Derived'
>>>

However, this fails if one does not provide an argument:

>>> t = testInheritance.Third()
>>> t.get_base().name()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    Derived.name(Derived)
did not match C++ signature:
    name(DerivedWrapper {lvalue})
    name(DerivedWrapper {lvalue})
>>> 

I cannot wrap my head around this, can anybody point me to what I am doing 
wrong? I would be very grateful!

Best regards,
Karl Bicker
#include<boost/python.hpp>

#include<massDependence.h>

namespace bp = boost::python;

struct Base {

	Base() { };
	virtual ~Base() { };

	virtual double do_stuff(double input) = 0;
	virtual std::string name() const { return "Base"; };

};

struct BaseWrapper : public Base,
                            bp::wrapper<Base>
{
	
	BaseWrapper() :
		Base(),
		bp::wrapper<Base>() { };

	BaseWrapper(const Base& base) :
		Base(base),
		bp::wrapper<Base>() { };

	double do_stuff(double input) {
		return this->get_override("do_stuff")(input);
	};

	std::string name() const {
		if(bp::override name = this->get_override("name")) {
			return name();
		}
		return Base::name();
	};

	std::string default_name() const {
		return Base::name();
	};

};

struct Derived : public Base
{

	Derived() : Base() { };
	virtual ~Derived() { };

	virtual double do_stuff(double input) { return (2. * input); };
	virtual std::string name() const { return "Derived"; };
  
};

struct DerivedWrapper : public Derived,
                               bp::wrapper<Derived>
{

	DerivedWrapper() :
		Derived(),
		bp::wrapper<Derived>() { };
	
	DerivedWrapper(const Derived& derived) :
		Derived(derived),
		bp::wrapper<Derived>() { };

	double do_stuff(double input) {
		if(bp::override do_stuff = this->get_override("do_stuff")) {
			return do_stuff(input);
		}
		return Derived::do_stuff(input);
	};

	double default_do_stuff(double input) {
		return Derived::do_stuff(input);
	};

	std::string name() const {
		if(bp::override name = this->get_override("name")) {
			return name();
		}
		return Derived::name();
	};

	std::string default_name() const {
		return Derived::name();
	};


};

struct Third
{
	Third(const boost::shared_ptr<Base>& base = boost::shared_ptr<Base>()) 
		: _base(base)
	{
		if(not _base) {
			_base = boost::shared_ptr<Base>(new Derived());
		}
	};

	Third(const Third& third) {
		_base = third._base;
	};

	const boost::shared_ptr<Base>& get_base() const {
		return _base;
	};

  private:

	boost::shared_ptr<Base> _base;

};

struct ThirdWrapper : public Third, bp::wrapper<Third>
{

	ThirdWrapper(const boost::shared_ptr<Base>& base = boost::shared_ptr<Base>())
		: Third(base), bp::wrapper<Third>() { };

	ThirdWrapper(const Third& third)
		: Third(third), bp::wrapper<Third>() { };

};

BOOST_PYTHON_MODULE(testInheritance) {

	bp::class_<BaseWrapper, boost::noncopyable>("Base", bp::no_init)
		.def("do_stuff", bp::pure_virtual(&BaseWrapper::do_stuff))
		.def("name", &BaseWrapper::name, &BaseWrapper::default_name);

	bp::class_<DerivedWrapper, bp::bases<Base> >("Derived")
		.def("do_stuff", &DerivedWrapper::do_stuff, &DerivedWrapper::default_do_stuff)
		.def("name", &DerivedWrapper::name, &DerivedWrapper::default_name);

	bp::class_<ThirdWrapper>("Third", bp::no_init)
		.def(bp::init<bp::optional<boost::shared_ptr<Base> > >())
		.def(
			"get_base"
			, &Third::get_base
			, bp::return_value_policy<bp::copy_const_reference>()
		);

	bp::register_ptr_to_python<boost::shared_ptr<Base> >();
	bp::register_ptr_to_python<boost::shared_ptr<Derived> >();
	bp::register_ptr_to_python<boost::shared_ptr<Third> >();

}
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to