Question on enable_shared_from_this [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
what is the usefulness of enable_shared_from_this
I want to have an idea of what shared pointers are. So, I googled and had some insight into them. And I ran into a website which provided brief overview of the smaprt pointer concept. However, I could not undesrtand what they wanted to convey with the following (or rather how to achieve it).
Shared pointers in member functions
Sometimes a shared pointer to the current object is needed in its member function. Boost provides a mixin template class called enable_shared_from_this, which defines a no-argument member function called shared_from_this(). It returns a shared pointer to this. At least one instance of a shared pointer to this object must exist before the first use of this method; otherwise it has undefined results (usually crash). The best way to guarantee that this is condition met is to make the constructor protected and provide a factory method that returns a shared pointer to the newly created object.
class Foo : public enable_shared_from_this<Foo> {
public:
void someMethod() {
boost::shared_ptr<Foo> this_ = shared_from_this();
// use pointer...
}
...
static boost::shared_ptr<Foo> create() {
return boost::shared_ptr<Foo>(new Foo());
}
protected:
Foo() { ... }
...
};
Could someone please let me know how can an object of this class be created and what role does the create() method play here? (im trying to figure this out as we speak..but just in case!:))
Thanks,
Pavan,

This class ("mixin") is intended for classes that you know are going to need shared access. Instead of managing the shared_ptrs from outside the class, this allows the class to contain this information (that it is shared using shared_ptr) and thus avoid some common pitfalls.
When you used a share_ptr for something, a common pitfall is to initialize more than one share_ptr with the same raw pointer -
Bla *bla = new Bla;
shared_ptr<Bla> x(bla);
shared_ptr<Bla> y(bla);
This code has a bug, the two share_ptrs are not aware of each other and both will delete the pointer. If however you use this mixin, the class itself is responsible for managing its share_ptrs and this makes it impossible for this bug to occur since all share_ptrs of an instances are derived from the same source.
This is also why you would want the constructor to be private or protected. You don't want the user to be able to create instances of the class since that will allow him to write code like the above again.
The create function is an entry point for you, the class writer to instantiate the class. To call new and pass arguments to the constructor. boost doesn't want to call new for you since you might want to use an allocator or use a non-trivial c'tor.

Related

What is the need for enable_shared_from_this? [duplicate]

This question already has answers here:
What is the usefulness of `enable_shared_from_this`?
(6 answers)
Closed 6 years ago.
I am new to C++11 and I came across enable_shared_from_this. I do not understand what it is trying to achieve? So I have a program that uses enable_shared_from_this.
struct TestCase: enable_shared_from_this<TestCase>
{
std::shared_ptr<testcase> getptr() {
return shared_from_this();
}
~TestCase() { std::cout << "TestCase::~TestCase()"; }
};
int main()
{
std::shared_ptr<testcase> obj1(new TestCase);
std::shared_ptr<testcase> obj2 = obj1->getptr();
// The above can be re written as below
// std::shared_ptr<testcase> obj2 = shared_ptr<testcase>(obj1);
}
My question is when I need a pointer to 'this', why not use the obj itself. Why to return a 'this' from a function of that class like using getptr() and then returning shared_from_this()????
I do not understand.
Second question, if enable_shared_from_this is NOT used, why is the dtor called twice that creates a problem, a crash!!!!
Another way I can bypass using enable_shared_from_this is like this.
Add this in class TestCase
std::shared_ptr getptr1(shared_ptr obj) {
return std::shared_ptr(obj);
}
and from main make a call this this:
std::shared_ptr bp2 = bp1->getptr1(bp1);
And done. We do not need enable_shared_from_this. Why on the earth do we need it??
A shared_ptr manages two different things. It has a pointer to its data, and a pointer to a reference counting block.
The reference counting block has a strong counter, a weak counter and a destroy operation in it.
When you std::shared_ptr<X>(pX), it creates a new reference counting block that, when the last (strong) reference goes away, it deletes the pX object.
The same thing happens when you std::shared_ptr<X>(this).
So, if you wrap an object in std::shared_ptr in two different spots, you have to different reference counting blocks, and they both want to destroy the object when they go away.
enable_shared_from_this<X> changes how this works. When you create a shared pointer to an object inheriting from it, it stores a std::weak_ptr<X> inside the enable_shared_from_this<X>. A weak pointer stores a pointer to the above reference counting block, but only "holds" a weak reference (not a strong one).
Then, when you call shared_from_this(), it does a .lock() on that weak pointer and returns a shared pointer using the reference counting block of the old one created (as stored by the weak_ptr).
Now, the above is an example implementation of what it could do: the standard mandates behavior, not implementation, and the weak_ptr is a possible way to implement it. Similarly, the reference counting block detail is just an example implementation.
The core issue is that two independent shared pointers wrapping the same pointer will try to independently manage the pointer's lifetime. enable_shared_from_this makes the first smart pointer's reference counting block be used by later shared_from_this() return values.
Short answer: you need enable_shared_from_this when you need to use inside the object itself existing shared pointer guarding this object.
Out of the object you can simply assign and copy a shared_ptr because you deal with the shared_ptr variable as is. But when you are in one of the class members then if you need to use a shared pointer pointing to self object (instead of ordinary this) and there is no such shared pointer in arguments of that method then shared_from_this() is what will help you.
Using std::make_shared(this) is absolutely unsafe as you can not have two shared pointers on the same object. While, shared_from_this() is safe because it uses weak_ptr to "resolve" already existing shared_ptr.
To be able to use shared_from_this() you must first use enable_shared_from_this in your class definition which adds a shared_from_this() method to your class.
Note, shared_from_this() can not be used in the class constructor! At that time the shared_ptr does not exist yet, so the shared_from_this() can't resolve any exisiting pointers.
And when and why one can need a shared pointer to this instead of just this it is quite other question. For example, it is widely used in asynchronous programming for callbacks binding.

Initializing shared_ptr member variable, new vs make_shared?

When initializing a shared_ptr member variable:
// .h
class Customer
{
public:
Customer();
private:
std::shared_ptr<OtherClass> something_;
}
// .cpp
Customer():
something_(new OtherClass())
{
}
vs.
Customer():
something_(std::make_shared<OtherClass>())
{
}
Is the make_shared version allowed? I always seem to see the first version, which is preferred?
The only times when make_shared is not allowed are:
If you're getting a naked pointer allocated by someone else and storing it in shared_ptr. This is often the case when interfacing with C APIs.
If the constructor you want to call is not public (make_shared can only call public constructors). This can happen with factory functions, where you want to force users to create the object from the factory.
However, there are ways to get around this. Instead of having a private constructor, have a public constructor. But make the constructor take a type with can only be constructed by those with private access to the class. That way, the only people who can call make_shared with that object type are those with private access to the class.
So yes, you can do this.
In this case, using make_shared is not just allowed, but it is better to use it. If you use new, it will allocate memory for your Customer somewhere and then memory for your shared_ptr somewhere else, storing both strong and weak references (for weak pointers and shared pointers). If you use the make_shared you would have only one place in memory with everything and therefore only one new.
I'm not sure that I was really clear, this was the purpose of the GotW #89, read it, it is well explained there.

C++11 Convert traditional pointer to smart pointer. Using up-to-date SVN Clang and libc++ from llvm

I've got a function inside a class (A) that essentially takes as a parameter a pointer to another class (B). The B class is inherited by multiple other classes which it should also accept.
What I would like to do is take ownership of this pointer to store for later use in the class, it won't be used outside the class again for anything else. While I would make the parameter a shared_ptr, I would like to avoid that as much as possible due to other people I work with who don't quite get the whole smart pointer thing. Is there any way to do this?
Here's a sort of example that I would like to do, although from what I've tested this doesn't work.
//In .h file
std::vector< unique_ptr< B > > data_store;
//In .cpp file
void A::add_data(B* NewItem)
{
data_store.resize(data_store.size()+1);
data_store[data_store.size()-1] = NewItem;
}
Second to that, I would like to maybe use a copy constructor or something similar to use a smart pointer inside the class: with what I'm having to do it could get a bit ugly if I have to do manual deletes. The problem with that is that I don't know whether it's the base class (B) coming in or whether it's a class that inherited from B. I'm not too sure how to deal with that without having to hard-code in some kind of checkable ID for the class and using the correct copy/move constructors, which I would like to avoid at all costs.
I'm using an updated Clang and libC++ from llvm which I updated about 10am UK time on 12th March 2012.
For any pointer that isn't supposed to be shared, which the class has sole ownership of the std::unique_ptr<T> is the correct choice. It will automatically delete the pointer when the owning object goes out of scope/is deleted. I would actually advice against using a shared pointer for this at all, as it would communicate to other developers that this member is supposed to be shared.
So for the copying. Since you have a pointer to an object which might have subclasses you need to use the clone idiom instead of a normal copy constructor. It is normally implemented by having a virtual clone function which returns a pointer (or a smart pointer) to the class. This requires all subclasses to reimplement this, returning a copy of itself.
class Base {
...
virtual std::unique_ptr<Base> clone() const = 0;
...
};
class Subclass {
...
virtual std::unique_ptr<Base> clone() const {
return std::unique_ptr<Base>(new Subclass(*this));
}
};
If the owning object has a copy constructor it will have to invoke this clone member function on the object it owns when creating a copy of itself.
If you wish to creater object, that owns vector of pointers you should use boost::vector_ptr. It automatically deletes all objects contained in itself

Get (pointer to) calling object

I have an object -a scheduler class-. This scheduler class is given member function pointers, times and the pointer to the object which created the scheduler.
This means I could do something as much as: (pObject->*h.function)(*h.param); Where pObject is the pointer to the original object, h a class which contains the function + void pointer parameter so I can pass arguments to the original function.
When I like to initialize this object I have the explicit Scheduler(pObjType o); constructor (where pObjType is a template parameter).
When I create an object which should have this alarm I type:
struct A {
typedef void (A::*A_FN2)(void*);
typedef Scheduler<A*,A_FN2> AlarmType;
A(int _x) : alarm(NULL)
{
alarm.SetObject(this);
}
AlarmType alarm
However this alarm-type puts quite a big limitation on the object: if I forget to add a copy-constructor (to A) the class would get undefined behaviour. The scheduler would keep pointing to the original object, and that original object might go out of scope, or even worse, might not.
Is there a method that when I copy my alarm (by default, so in the scheduler's copy-constructor) I can get the calling object (and pointer to that?)?
Or if that isn't possible, is it possible to throw a (compile) error if I forget to implement a copy-constructor for my structure? - And try to copy this structure somewhere?
As I see it, you have an opportunity to improve your design here, that may help you get rid of your worry.
It is usually a bad idea to pass
around member function pointers. It
is better to make your structs
inherit from an abstract base class,
making the functions you want to
customize abstract virtual.
If you don't need copying, it is best
to disallow it in the base class.
Either by making the copy constructor and operator undefined and private,
or by inheriting boost::NonCopyable.
If you want any kind of automatic copy construction semantics, then you're going to need to go to the CRTP- no other pattern provides for a pointer to the owning object.
The other thing is that you should really use a boost::/std::function<>, they're far more generic and you're going to need that if you want to be able to use Lua functions.
The simplest way to prevent the specific issue you're asking about is to make Scheduler noncopyable (e.g. with boost::noncopyable). This means that any client class incorporating a value member of type Scheduler will fail to be copyable. The hope is that this provides a hint for the programmer to check the docs and figure out the copy semantics of Scheduler (i.e. construct a new Scheduler for every new A), but it's possible for someone to get this wrong if they work around the problem by just holding the Scheduler by pointer. Aliasing the pointer gives exactly the same problem as default-copy-constructing the Scheduler instance that holds a pointer.
Any time you have raw pointers you have to have a policy on object lifetime. You want to ensure that the lifetime of any class A is at least as long as the corresponding instance of Scheduler, and as I see it there are three ways to ensure this:
Use composition - not possible in this case because A contains a Scheduler, so Scheduler can't contain an A
Use inheritance, e.g. in the form of the Curiously Recurring Template Pattern (CRTP)
Have a global policy on enforcing lifetimes of A instances, e.g. requiring that they are always held by smart pointer, or that cleaning them up is the responsibility of some class that also knows to clean up the Schedulers that depend on them
The CRTP could work like this:
#include <iostream>
using namespace std;
template<typename T>
struct Scheduler {
typedef void (T::* MemFuncPtr)(void);
Scheduler(MemFuncPtr action) :
action(action)
{
}
private:
void doAction()
{
this->*action();
}
MemFuncPtr action;
};
struct Alarm : private Scheduler<Alarm> {
Alarm() : Scheduler<Alarm>(&Alarm::doStuff)
{
}
void doStuff()
{
cout << "Doing stuff" << endl;
}
};
Note that private inheritance ensures that clients of the Alarm class can't treat it as a raw Scheduler.

Where to delete an object created by factory?

If I have a factory, that creates an object and returns a pointer to it, what will be a better way to delete it:
By delete call in the "user" code, or by a new DestructObject function which I should have together with the factory?
In the general case, the factory might not use plain old new to allocate the object. It may use object and/or page pooling, malloc with placement new, or something even more exotic (memory mapping?). There are at least three ways to handle this that I can think of:
Have the factory supply a recycle method to be called when you are done with the object.
Return a smart pointer that knows how to do away with the object once no referers remain.
Implement a custom delete operator in the object itself.
I hesitate to recommend one over the other, since I haven't given it enough thought in the last five minutes to proffer a definitive opinion, but I would tend to favour the last option in combination with a regular smart pointer like boost/tr1::shared_ptr.
The best way to delete it manually would be not at all.
The following code provides an opportunity not to think about who should remove the newly created object.
class FooFactory
{
public:
static std::auto_ptr<Foo> CreateInstance();
};
// transmit ownership of created object from factory to 'a' variable
std::auto_ptr<Foo> a = FooFactory::CreateInstance();
// using the created object is not required
FooFactory::CreateInstance();
The most versatile solution for this problem is to derive your class from a base class that has a virtual "killing" function. Something like this:
class IDisposable {
public:
virtual void Release() = 0;
};
It's generally believed that polymorphic objects should have virtual destructors to support proper object cleanup. However this is incomplete, because it doesn't account for potentially different memory management of objects.
On the other hand this method doesn't require to use virtual destructors. It's now replaced by Release function that does both: invokation of the correct destructor and releasing the memory by the appropriate means.
takes care of the object destr
both: destruct
The object returned from the factory will implement this "interface".