[C++-sig] weak_ptr to this in C++ classes extended from python
Bryan Catanzaro
bcatanzaro at acm.org
Thu Apr 26 18:43:55 CEST 2012
Holger Brandsmeier <brandsmeier <at> gmx.de> writes:
>
> Dear list,
>
> how is it possible to have a class in C++ that can be extended from
> python and that stores a weak_ptr to itself?
Have you tried using boost::enable_shared_from_this? The following example code
seems to do what you want.
------------ foo.cpp ------------
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <iostream>
//Inheriting boost::enable_shared_from_this adds a weak_ptr to the object
//That gets automatically initialized when you construct a shared_ptr
//holding the object.
class A
: public boost::enable_shared_from_this<A> {
static int counter;
public:
int id;
A() {
id = counter++;
std::cout << "Constructing A[" << id << "]" << std::endl;
}
~A() {
std::cout << "Destructing A[" << id << "]" << std::endl;
}
//This function allows us to get a shared_ptr holding the object
boost::shared_ptr<A> ptr() {
return shared_from_this();
}
};
int A::counter = 0;
using namespace boost::python;
class B {
boost::shared_ptr<A> m_a;
static int counter;
public:
int id;
//Notice that B accepts an A object directly
//And asks it for the shared_ptr which holds it.
B(A& a) : m_a(a.ptr()) {
id = counter++;
std::cout << "Constructing B[" << id << "]";
std::cout << ", which holds A[" << m_a->id << "]" << std::endl;
}
~B() {
std::cout << "Destructing B[" << id << "]";
std::cout << ", which holds A[" << m_a->id << "]" << std::endl;
}
};
int B::counter = 0;
BOOST_PYTHON_MODULE(foo) {
class_<A, boost::shared_ptr<A> >("A", init<>());
class_<B>("B", init<A&>());
}
-----------------------------------
------------ test.py ------------
import foo
class ExtendedA(foo.A):
def special(self):
return "successfully extended foo.A"
a0 = foo.A()
a = ExtendedA()
print a.special()
print "an ExtendedA object is a foo.A object: %s" % isinstance(a, foo.A)
b = foo.B(a)
-----------------------------------
On my system the output is:
Constructing A[0]
Constructing A[1]
successfully extended foo.A
an ExtendedA object is a foo.A object: True
Constructing B[0], which holds A[1]
Destructing B[0], which holds A[1]
Destructing A[1]
Destructing A[0]
More information about the Cplusplus-sig
mailing list