struct A {
static A* create () { return new A; }
std::string hello () { return "Hello, is there anybody in there?"; }
};
BOOST_PYTHON_MODULE(pointer)
{
class_<A>("A",no_init)
.def("create",&A::create, return_value_policy<manage_new_object>())
.staticmethod("create")
.def("hello",&A::hello)
;
}
A sample python program:
from pointer
import *
an_A = A.create()
print an_A.hello()
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>
using namespace boost;
using namespace std;
using namespace boost::python;
struct A {
static shared_ptr<A> create () { return shared_ptr<A>(new A); }
std::string hello () { return "Just nod if you can hear me!"; }
};
BOOST_PYTHON_MODULE(shared_ptr)
{
class_<A, shared_ptr<A> >("A",init<>())
.def("create",&A::create )
.staticmethod("create")
.def("hello",&A::hello)
;
}
The Node.cpp file:
#include <boost/python.hpp>
#include <osg/ref_ptr>
#include <osg/Node>
using namespace boost::python;
using namespace osg;
// Tag the OpenSceneGraph ref_ptr type as a smart pointer.
namespace boost {
namespace python {
template <class T> struct pointee< ref_ptr<T> >
{ typedef T type; };
}}
// Declare the actual type
BOOST_PYTHON_MODULE(Node) {
class_<Node, ref_ptr<Node> >("Node")
;
}
Shared pointers use reference counts to track the life cycle of an object. The tracked object is the resource to be managed. As long as a shared pointer exists, the reference count is positive, and then the resource is alive. When all shared pointers are destroyed to make the reference count decrease to zero, the resource object gets deleted.,So the boost::shared_ptr passed into C++ has a different reference count to the original shared pointer. The life cycle of the resource is collaboratively managed by both boost::shared_ptr and PyObject.,By using boost::enable_shared_from_this, the resource object knows where to find the original reference counter, so we can recover it from the shared pointer cooked by boost.python:,The C++ internal counter says there are 10 shared pointers to the resource, but the reference count of the boost::shared_ptr passed into show_count_from_python() is only 1!
def print_value(val):
msg = "the value is %s" % val
print(msg)
# "msg"
object gets automatically destroyed when the
function returns
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// compile with -std=c++11 -stdlib=libc++ to get C++11 support
#include <stdlib.h>
#ifdef USE_BOOST_SHARED_PTR
#include <boost/shared_ptr.hpp>
#define SHARED_PTR boost::shared_ptr
#else
#include <memory>
#define SHARED_PTR std::shared_ptr
#endif
struct Resource {
Resource() { printf("Resource %p constructed\n", this); }
~Resource() { printf("Resource %p destructed\n", this); }
};
int main(int argc, char ** argv) {
auto obj = SHARED_PTR<Resource>(new Resource);
printf("address %p, count %lu\n",
obj.get(), // getting the raw pointer
obj.use_count() // getting the reference count
);
// output: address 0x7fa970c03420, count 1
printf("reset obj\n");
obj = nullptr; // this resets the shared_ptr and thus release the resource object.
printf("program ends\n");
return 0;
}
auto * resource = new Resource();
auto ref1 = SHARED_PTR<Resource>(resource);
// ooops, the duplicated counter will end up with double free
auto ref2 = SHARED_PTR<Resource>(resource);
auto * resource = new Resource();
auto ref1 = SHARED_PTR<Resource>(resource);
// copy the first shared pointer to use its counter
auto ref2 = ref1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
Smart pointers std::unique_ptr std::shared_ptr Custom smart pointers
std::unique_ptr<Example> create_example() { return std::unique_ptr<Example>(new Example()); }
m.def("create_example", & create_example);
void do_something_with_example(std::unique_ptr<Example> ex) { ... }
py::class_<Example, std::shared_ptr<Example> /* <- holder type * /> obj(m, "Example");
class Child { };
class Parent {
public:
Parent() : child(std::make_shared<Child>()) { }
Child *get_child() { return child.get(); } /* Hint: ** DON'T DO THIS ** */
private:
std::shared_ptr<Child> child;
};
PYBIND11_MODULE(example, m) {
py::class_<Child, std::shared_ptr<Child>>(m, "Child");
py::class_<Parent, std::shared_ptr<Parent>>(m, "Parent")
.def(py::init<>())
.def("get_child", &Parent::get_child);
}
from example
import Parent
print(Parent().get_child())
Last Updated : 15 Nov, 2021,GATE CS 2021 Syllabus
Output:
A::show()
0x1b42c20
A::show()
0
0x1b42c20
std::unique_ptr was developed in C++11 as a replacement for std::auto_ptr.
unique_ptr is a new facility with similar functionality, but with improved security (no fake copy assignments), added features (deleters) and support for arrays. It is a container for raw pointers. It explicitly prevents copying of its contained pointer as would happen with normal assignment i.e. it allows exactly one owner of the underlying pointer.
So, when using unique_ptr there can only be at most one unique_ptr at any one resource and when that unique_ptr is destroyed, the resource is automatically claimed. Also, since there can only be one unique_ptr to any resource, so any attempt to make a copy of unique_ptr will cause a compile-time error.
unique_ptr<A> ptr1 (new A);
// Error: can't copy unique_ptr
unique_ptr<A> ptr2 = ptr1;
But, unique_ptr can be moved using the new move semantics i.e. using std::move() function to transfer ownership of the contained pointer to another unique_ptr.
// Works, resource now stored in ptr2
unique_ptr<A> ptr2 = move(ptr1);
This page was last modified on 25 May 2022, at 12:32.
void del(void(*)()) {}
void fun() {}
int main(){
std::shared_ptr<void()> ee(fun, del);
(*ee)();
}
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
struct Base
{
Base() { std::cout << " Base::Base()\n"; }
// Note: non-virtual destructor is OK here
~Base() { std::cout << " Base::~Base()\n"; }
};
struct Derived: public Base
{
Derived() { std::cout << " Derived::Derived()\n"; }
~Derived() { std::cout << " Derived::~Derived()\n"; }
};
void thr(std::shared_ptr<Base> p)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::shared_ptr<Base> lp = p; // thread-safe, even though the
// shared use_count is incremented
{
static std::mutex io_mutex;
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << "local pointer in a thread:\n"
<< " lp.get() = " << lp.get()
<< ", lp.use_count() = " << lp.use_count() << '\n';
}
}
int main()
{
std::shared_ptr<Base> p = std::make_shared<Derived>();
std::cout << "Created a shared Derived (as a pointer to Base)\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
std::thread t1(thr, p), t2(thr, p), t3(thr, p);
p.reset(); // release ownership from main
std::cout << "Shared ownership between 3 threads and released\n"
<< "ownership from main:\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
t1.join(); t2.join(); t3.join();
std::cout << "All threads completed, the last one deleted Derived\n";
}
Base::Base()
Derived::Derived()
Created a shared Derived(as a pointer to Base)
p.get() = 0x2299b30, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
p.get() = 0, p.use_count() = 0
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 5
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 3
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 2
Derived::~Derived()
Base::~Base()
All threads completed, the last one deleted Derived