I have a function which takes a shared_ptr<MyClass>.
In some member function memfun of MyClass, I need to pass this to that function. But if I write
void MyClass:memfun()
{
func(shared_ptr<MyClass>(this))
}
I am assuming that after the call has ended the reference count will reach 0 and this will be attempted to be destroyed, which is bad.
Then I remembered that there this class enable_shared_from_this with the function shared_from_this.
So now I am going to use the following:
class MyClass: public enable_shared_from_this<MyClass>
{
void MyClass:memfun()
{
func(shared_from_this());
}
};
Questions are:
1) Is is absolutely impossible to use the functionality without deriving from enable_shared_from_this?
2) Does deriving from enable_shared_from_this mean that calling memfun on an object with automatic storage duration will result in something bad? E.g.
int main()
{
MyClass m; //is this OK?
m.memfun(); // what about this?
}
3) If I derive from MyClass, will the enable_shared_from_this functionality be correctly inherited or do I need to derive again? That is,
class MyCoolClass: public Myclass
{
void someCoolMember
{
someCoolFuncTakingSharedPtrToMyCoolClass(shared_from_this());
}
}
Is this OK? Or correct is the following?
class MyCoolClass: public Myclass, public enable_shared_from_this<MyCoolClass>
{
void someCoolMember
{
someCoolFuncTakingSharedPtrToMyCoolClass(enable_shared_from_this<MyCoolClass>::shared_from_this());
}
}
Thanks very much in advance.
1) It depends on what you mean by "do this" as to whether or not you can. You can always construct a shared_ptr from a raw pointer such as this, but it won't share the reference count with another shared_ptr instance that was separately constructed from a raw pointer. You will thus need to use a custom deleter on one or other instance to avoid double deletions, but unless you take great care then you may end up with dangling shared_ptr instances due to the object being deleted through one, but still accessible from another.
shared_from_this enables you to guarantee that if you have one shared_ptr instance to your object then you can construct another without copying the first, and that these instances will share the reference count. You could achieve this by storing a weak_ptr as a class member, and setting that value when you first allocate a shared_ptr to your object.
2) Calling shared_from_this() requires that there is at least one shared_ptr instance already pointing to your object. If you use it on an automatic object without a shared_ptr instance with a custom deleter then you will get bad stuff happening.
3) If you derive from your class then the enable_shared_from_this functionality will give you a shared_ptr to the base class (the one that derived from enable_shared_from_this). You could then use static_pointer_cast or dynamic_pointer_cast to cast the result of shared_from_this() to a pointer to the derived class.
The important question here is why does the function take the argument through a shared_ptr. Does it store the pointer internally for later use? Does it only use it for the duration of the call? Why is the ownership diluted among the caller and the callee?
Some answers suggest that you provide a no-op deleter if you are going to pass a stack allocated object into the function, but if the function is actually storing the shared_ptr for later use, it might be the case that by the time it gets around to it, the locally allocated object is no longer in the stack and you trigger UB. Having the no-op deleter shared_ptr will allow the call, but the semantics will not be correct.
If the function does not store the shared_ptr for later use, what was the design decision that led to that API? If you can change the function (and there is no impending reason), make it receive the argument by reference and you will have a friendlier interface that does not impose a shared_ptr for no reason.
If at the end you determine that you can guarantee that the object in the stack will be alive for the whole duration of the process triggered by that function call, then and only then use the no-op deleter.
1) No, it's not impossible to do this without shared_from_this. You can simply construct a shared_ptr with a no-op deleter:
void do_nothing(MyClass*) {}
void MyClass:memfun()
{
func(shared_ptr<MyClass>(this, do_nothing));
}
Seeing as you don't actually seem to need shared_from_this after all, I'm going to skip the next two parts of your question.
If you have an object with automatic storage and a function that requires shared_ptr and you know that the lifetime of your object will be long enough for the duration of the function and that it does not store the shared_ptr anywhere, then you can pass it with a no-op deleter.
This is useful for static objects. If it really does have local automatic storage, you need to ask yourself why the function is taking shared_ptr. Does it store them?
There is another lesser-known constructor to shared_ptr for an object that is a member of another reference-counted object. You can actually create a shared_ptr with the shared_ptr from the outer object and the pointer from the inner object.
In addition with David Rodríguez - dribeas, shared pointer isn't recommended by google
It maintains reference count internally, so making it work correctly, InterlockedIncrement and InterlockedDecrement are used, these two functions are really slower than normal ++ and --.
You should check this object ownership truly need be shared with others, per my experience, shared pointer could be avoided in most cases.
Related
class myMem{};
class Test{
public:
initMem1(myMem& mInput){/*initialize _mem1*/}
initMem2(shared_ptr<myMem> &pmInput){/*initialize _mem2*/}
myMem _mem1;
shared_ptr<myMem> _mem2;
};
Test myTest;
myTest()
So, in the code above, members belong to a class. One member is a value type and another member is a shared_ptr type. Which way is better for a class member? Moreover, I also have the functions to initialize the members. Which way is better?
In general what is the advantage of passing by reference to shared_ptr over passing by reference directly?
The only reason a function should accept a std::shared_ptr as a argument is if it may need to share or modify the ownership of the resource. If not, don't pass a std::shared_ptr.
If the function will definitely need to take shared ownership then it should accept a std::shared_ptr by value. Only accept a std::shared_ptr& if the function may or may not take shared ownership.
If the function does not modify ownership then pass a reference to the resource, not a std::shared_ptr.
See: CppCoreGuidelines: F.7, R.30, R.34, R.35
Let's look inside your functions. For initmem1, the code usually looks like
initMem1(myMem& mInput){ _mem1 = mInput; }
We can see the call of an assignment operator, which usually copies all myMem fields.
For initMem2, there are two cases
1)
initMem2(shared_ptr<myMem> &pmInput){
_mem2 = pmInput;
}
You should use 'initMem2(const shared_ptr &pmInput)'. It's a good style.
We can see the fast initialization here. Just links are copied. But you get ownership sharing. If you change pmInput outside then _mem2 changes too.
No copy cunstructor is needed. Both smart ptrs holds the unique object.
2)
initMem2(const shared_ptr<myMem> &pmInput){ // of course, const
_mem2.reset(*pmInput);
}
You create a new shared_ptr with new content originally copied from pmInput.
You can change pmInput and _mem2 independently. But you get additional "new/delete calls" for this new shared_ptr and the copy constructor call.
One use case is when the original shared_ptr can change its contents in the middle of the function (perhaps a nested call) and the function is prepared to it and wants the new contents.
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.
With respect to smart pointers and new C++11/14 features, I am wondering what the best-practice return values and function parameter types would be for classes that have these facilities:
A factory function (outside of the class) that creates objects and returns them to users of the class. (For example opening a document and returning an object that can be used to access the content.)
Utility functions that accept objects from the factory functions, use them, but do not take ownership. (For example a function that counts the number of words in the document.)
Functions that keep a reference to the object after they return (like a UI component that takes a copy of the object so it can draw the content on the screen as needed.)
What would the best return type be for the factory function?
If it's a raw pointer the user will have to delete it correctly which is problematic.
If it returns a unique_ptr<> then the user can't share it if they want to.
If it's a shared_ptr<> then will I have to pass around shared_ptr<> types everywhere? This is what I'm doing now and it's causing problems as I'm getting cyclic references, preventing objects from being destroyed automatically.
What is the best parameter type for the utility function?
I imagine passing by reference will avoid incrementing a smart pointer reference count unnecessarily, but are there any drawbacks of this? The main one that comes to mind is that it prevents me from passing derived classes to functions taking parameters of the base-class type.
Is there some way that I can make it clear to the caller that it will NOT copy the object? (Ideally so that the code will not compile if the function body does try to copy the object.)
Is there a way to make it independent of the type of smart pointer in use? (Maybe taking a raw pointer?)
Is it possible to have a const parameter to make it clear the function will not modify the object, without breaking smart pointer compatibility?
What is the best parameter type for the function that keeps a reference to the object?
I'm guessing shared_ptr<> is the only option here, which probably means the factory class must return a shared_ptr<> also, right?
Here is some code that compiles and hopefully illustrates the main points.
#include <iostream>
#include <memory>
struct Document {
std::string content;
};
struct UI {
std::shared_ptr<Document> doc;
// This function is not copying the object, but holding a
// reference to it to make sure it doesn't get destroyed.
void setDocument(std::shared_ptr<Document> newDoc) {
this->doc = newDoc;
}
void redraw() {
// do something with this->doc
}
};
// This function does not need to take a copy of the Document, so it
// should access it as efficiently as possible. At the moment it
// creates a whole new shared_ptr object which I feel is inefficient,
// but passing by reference does not work.
// It should also take a const parameter as it isn't modifying the
// object.
int charCount(std::shared_ptr<Document> doc)
{
// I realise this should be a member function inside Document, but
// this is for illustrative purposes.
return doc->content.length();
}
// This function is the same as charCount() but it does modify the
// object.
void appendText(std::shared_ptr<Document> doc)
{
doc->content.append("hello");
return;
}
// Create a derived type that the code above does not know about.
struct TextDocument: public Document {};
std::shared_ptr<TextDocument> createTextDocument()
{
return std::shared_ptr<TextDocument>(new TextDocument());
}
int main(void)
{
UI display;
// Use the factory function to create an instance. As a user of
// this class I don't want to have to worry about deleting the
// instance, but I don't really care what type it is, as long as
// it doesn't stop me from using it the way I need to.
auto doc = createTextDocument();
// Share the instance with the UI, which takes a copy of it for
// later use.
display.setDocument(doc);
// Use a free function which modifies the object.
appendText(doc);
// Use a free function which doesn't modify the object.
std::cout << "Your document has " << charCount(doc)
<< " characters.\n";
return 0;
}
I'll answer in reverse order so to begin with the simple cases.
Utility functions that accept objects from the factory functions, use them, but do not take ownership. (For example a function that counts the number of words in the document.)
If you are calling a factory function, you are always taking ownership of the created object by the very definition of a factory function. I think what you mean is that some other client first obtains an object from the factory and then wishes to pass it to the utility function that does not take ownership itself.
In this case, the utility function should not care at all how ownership of the object it operates on is managed. It should simply accept a (probably const) reference or – if “no object” is a valid condition – a non-owning raw pointer. This will minimize the coupling between your interfaces and make the utility function most flexible.
Functions that keep a reference to the object after they return (like a UI component that takes a copy of the object so it can draw the content on the screen as needed.)
These should take a std::shared_ptr by value. This makes it clear from the function's signature that they take shared ownership of the argument.
Sometimes, it can also be meaningful to have a function that takes unique ownership of its argument (constructors come to mind). Those should take a std::unique_ptr by value (or by rvalue reference) which will also make the semantics clear from the signature.
A factory function (outside of the class) that creates objects and returns them to users of the class. (For example opening a document and returning an object that can be used to access the content.)
This is the difficult one as there are good arguments for both, std::unique_ptr and std::shared_ptr. The only thing clear is that returning an owning raw pointer is no good.
Returning a std::unique_ptr is lightweight (no overhead compared to returning a raw pointer) and conveys the correct semantics of a factory function. Whoever called the function obtains exclusive ownership over the fabricated object. If needed, the client can construct a std::shared_ptr out of a std::unique_ptr at the cost of a dynamic memory allocation.
On the other hand, if the client is going to need a std::shared_ptr anyway, it would be more efficient to have the factory use std::make_shared to avoid the additional dynamic memory allocation. Also, there are situations where you simply must use a std::shared_ptr for example, if the destructor of the managed object is non-virtual and the smart pointer is to be converted to a smart pointer to a base class. But a std::shared_ptr has more overhead than a std::unique_ptr so if the latter is sufficient, we would rather avoid that if possible.
So in conclusion, I'd come up with the following guideline:
If you need a custom deleter, return a std::shared_ptr.
Else, if you think that most of your clients are going to need a std::shared_ptr anyway, utilize the optimization potential of std::make_shared.
Else, return a std::unique_ptr.
Of course, you could avoid the problem by providing two factory functions, one that returns a std::unique_ptr and one that returns a std::shared_ptr so each client can use what best fits its needs. If you need this frequently, I guess you can abstract most of the redundancy away with some clever template meta-programming.
What would the best return type be for the factory function?
unique_ptr would be best. It prevents accidental leaks, and the user can release ownership from the pointer, or transfer ownership to a shared_ptr (which has a constructor for that very purpose), if they want to use a different ownership scheme.
What is the best parameter type for the utility function?
A reference, unless the program flow is so convoluted that the object might be destroyed during the function call, in which case shared_ptr or weak_ptr. (In either case, it can refer to a base class, and add const qualifiers, if you want that.)
What is the best parameter type for the function that keeps a reference to the object?
shared_ptr or unique_ptr, if you want it to take responsibility for the object's lifetime and not otherwise worry about it. A raw pointer or reference, if you can (simply and reliably) arrange for the object to outlive everything that uses it.
Most of the other answers cover this, but #T.C. linked to a few really good guidelines which I'd like to summarise here:
Factory function
A factory that produces a reference type should return a unique_ptr by default, or a shared_ptr if ownership is to be shared with the factory.
-- GotW #90
As others have pointed out, you as the recipient of the unique_ptr can convert it to a shared_ptr if you wish.
Function parameters
Don’t pass a smart pointer as a function parameter unless you want to use or manipulate the smart pointer itself, such as to share or transfer ownership.
Prefer passing objects by value, *, or &, not by smart pointer.
-- GotW #91
This is because when you pass by smart pointer, you increment the reference counter at the start of the function, and decrement it at the end. These are atomic operations, which require synchronisation across multiple threads/processors, so in heavily multithreaded code the speed penalty can be quite high.
When you're in the function the object is not going to disappear because the caller still holds a reference to it (and can't do anything with the object until your function returns) so incrementing the reference count is pointless if you're not going to keep a copy of the object after the function returns.
For functions that don't take ownership of the object:
Use a * if you need to express null (no object), otherwise prefer to use a &; and if the object is input-only, write const widget* or const widget&.
-- GotW #91
This doesn't force your caller to use a particular smart pointer type - any smart pointer can be converted into a normal pointer or a reference. So if your function doesn't need to keep a copy of the object or take ownership of it, use a raw pointer. As above, the object won't disappear in the middle of your function because the caller is still holding on to it (except in special circumstances, which you would already be aware of if this is an issue for you.)
For functions that do take ownership of the object:
Express a “sink” function using a by-value unique_ptr parameter.
void f( unique_ptr<widget> );
-- GotW #91
This makes it clear the function takes ownership of the object, and it's possible to pass raw pointers to it that you might have from legacy code.
For functions that take shared ownership of the object:
Express that a function will store and share ownership of a heap object using a by-value shared_ptr parameter.
-- GotW #91
I think these guidelines are very useful. Read the pages the quotes came from for more background and in-depth explanation, it's worth it.
I would return a unique_ptr by value in most situations. Most resources shouldn't be shared, since that makes it hard to reason about their lifetimes. You can usually write your code in such a way to avoid shared ownership. In any case, you can make a shared_ptr from the unique_ptr, so it's not like you're limiting your options.
I am wondering what might be the best way to accomplish a design dilemma in C++ ...
I have a class, which contains member variables of type Base of another class, and the real objects that are created are created as Derived of Base.
The class does not need to modify these variables, it is only using them. Someone else is creating these variables. These Derived classes also need to go to container (std::vector, QList, etc) classes in my class, so they should perform proper copy construction and assignment.
So, I was wondering what might be the best:
Create the member variables as a Base* and let us manage them and the memory they use. This leads to the classical memory leak issues... Someone just forgets to delete the object when they are not using it anymore.
Create the member variables as a Base& and let's pray that they do not disappear when they go out of scope somewhere.
Having reference member variables is always a poor choice because the compiler generated assignment and move assignment do the wrong thing, or not what one would expect.
Stick to pointers or smart pointers for member variables.
#hansmaad is just right, if you have a problem in controlling life time of the object you should share its ownership with those who create or manage it.
You have 2 options:
1) boost::shared_ptr or std::tr1::shared_ptr
You can easily use this class for any type Base without changing Base, but if you are working in a multi threaded environment it is very hard to achieve thread safety for shared_ptr and do not forget if you create an object as shared using one of this classes you should not manage the life time of the object directly and it is not legal to create a new shared object from raw pointer and you should always copy construct shared object. for example:
boost::shared_ptr<Base> sharedObject( new Drived() );
boost::shared_ptr<Base> validCopy( sharedObject ); // Ok share ownership
Base* p = sharedObject.get();
boost::shared_ptr<Base> invalidCopy( p ); // Error, can't create new shared_ptr from raw pointer
2) boost::intrusive_ptr
You can easily make it thread safe and you can pass it as either raw pointer or smart pointer since it can constructed from raw pointer because reference counting is implemented in the class instead but you should change definition of the class and add you reference counting mechanism
I would go with pointers, both for your vectors (i.e., vector<Base *>, not vector<Base>) and your container class for the following reasons:
If you store the Derived objects in a vector, that vector may get re-sized, which causes all the objects to 'move' to new locations in memory. This would invalidate all outstanding pointers and references
If your container contains references, you are not able to copy it as easily as you would if it contains pointers, as references can only be bound when defined (so in the constructor via MyClass::MyClass(int &a) : memberA(a) {}, if memory serves)
Pointers can be changed via other means such as set methods as needed, and can be set to null in the event of an absence of information
As far as ownership goes, jrok was the first to say it: shared_ptr<> is your friend. Don't reinvent the wheel, just make use of the standard library to simplify things for you. The only thing you would need to worry about in that case is circular pointers (i.e., the object points to itself, so there is always a valid pointer).
The first thing to consider with reference member variables is whether your class (not Derived, the class that's going to have a data member that is a pointer or a reference to Base) needs value semantics (which is another way of saying, "copies and assigns properly").
If so, then reference member variables are more or less out of the question straight away, because they can't be reseated. There are some odd situations where you can use them anyway, but you might as well assume that you won't, and use pointers.
Reference data members are occasionally useful for types that have "entity semantics" (that is, they don't assign at all and may or may not copy), but still they don't gain you a great deal. They can also lure you into the error of writing a constructor that takes a const Base& parameter, and storing it in a reference data member[*].
Who owns the object (and is responsible for freeing it) is completely independent of whether you use a pointer or a reference. There's probably a general convention not to use references for things you own (and there should be a convention not to use raw pointers for things you own, you should choose or write a suitable smart pointer. Smart pointer classes can hold a raw pointer). But that is just convention. You shouldn't assume that you manage the memory if and only if you have a pointer.
Summary: use a pointer, then make a separate decision how the memory is managed.
[*] This is a mistake, because eventually someone will accidentally use a temporary object in an initializer, and then the instance of your class with its reference data member will outlive the temporary. For this reason, things that store references for use after they return shouldn't take const & parameters, even if they don't modify the object. They can take const * instead. In C++11 I suppose they might be OK if there is also an rvalue reference overload, to prevent the const& overload being selected for temporaries, but it's not something I've tried out yet.
You should think about ownership. Whe owns that objects? If there is no clear answer to this questions, you should use a std::shared_ptr<Base> (shared ownership). If there is one class that owns that objects and all others just use them, you could use a std::unique_ptr<Base>, a pointer container like boost::ptr_vector or if there is no polymorphism it that owning classes just the concrete instance. In all other classes you can use plain pointers (prefered as class members) or references (prefered as arguments, if null is not allowed) to that objects.
Case 1 - Shared ownership
class IWorkOnBaseObjects
{
std::vector<std::shared_ptr<Base>> mySubset;
};
class MeToo
{
std::shared_ptr<Base> iNeedThisOne;
};
Case 2
class HomeOfBaseObjects
{
std::vector<std::uniqe_ptr<Base>> baseObjects;
};
class IWorkOnBaseObjects
{
std::vector<Base*> mySubset;
};
Case 3
class A : public Base{};
class B : public Base{};
class HomeOfAObjects
{
std::vector<A> aObjects;
};
class HomeOfBObjects
{
std::vector<B> bObjects;
};
class INeedABaseObject
{
Base* thisOne;
};
I have a reference to an object and want to call a function that takes a boost::shared_ptr of this object. If I build a boost::shared_ptr to make the call when my boost::shared_ptr is canceled from the stack than the object is canceled too! This is exactly what happens when I run this code:
double f(boost::shared_ptr<Obj>& object)
{
...
}
double g(Obj& object)
{
boost::shared_ptr<Obj> p(&object);
double x = f(p);
...
}
Is there a way to make it work? How can I create in g() a boost::shared pointer that leaves my object alive at the end? I think I have to connect it to the reference counting machinery of other shared pointers that already point to object... but how?
Even if I make it work do you think this way of doing is bad design? What is the best practice to solve this kind of problems? In my code I have objects and methods that work both with shared pointer and references and I cannot work only with these or those...
A function that takes a shared_ptr is saying something about what it does. It is saying, "I want to potentially claim shared ownership of this object". If this is not true, then it is a poorly written function and shouldn't be taking a shared_ptr at all.
A function which takes a value by non-const reference to an object means that the function can modify the object, but cannot claim ownership. If you don't own something, you also can't give ownership to someone else.
Now, you could perform this trick of using an empty deleter function:
void EmptyDeleter(Obj *) {}
double g(Obj& object)
{
boost::shared_ptr<Obj> p(&object, EmptyDeleter);
double x = f(p);
...
}
However, you are now lying to f. It doesn't own object; it can't own object. It is very possible that object is a stack object that may disappear any time after f completes. If f were a member of a class, it might store the shared_ptr in a member variable. At which point, it would then have a shared_ptr to a dead object. This is exactly the sort of thing that shared_ptrs are intended to prevent.
The correct answer is for either f to not take its argument by shared_ptr (use non-const reference or non-const pointer if it is modifiable, and const& if it is not modifiable), or for g to take its argument by shared_ptr.
You may create a shared_ptr that doesn't actually free the object. Like this:
struct FictiveDisposer {
template <class T> void operator ()(T) {}
};
Obj& object = /* ... */;
boost::shared_ptr<Obj> myPtr(&obj, FictiveDisposer ());
// you may use myPtr
However you should use this carefully. If you're sure the function you're calling won't try to "save" your object for later use - there's no problem. Otherwise you must guarantee that the lifetime of the saved shared_ptr to your object won't exceed the actual lifetime of your object.
In simple words: you got the reference to the object. You didn't create it, and you may not affect its lifetime (neither shared_ptr can). Hence there may happen a situation where the object doesn't exist anymore, still it's referenced by shared_ptr. This must be avoided.
You must consider the purpose of f(). Presumably if it takes a shared_ptr, f intends to retain shared ownership of this pointer over time, past its return. Why? What is f() assuming when you pass it a shared_ptr? Once you answer this question you will be able to figure out how to code g().
If for some reason f() does not need to retain shared ownership of the pointer, then if you have control over its interface it could be rewritten to take a Obj* or Obj& instead of a shared_ptr. Any code possessing a shared_ptr could then call f by pulling the pointer out of the shared_ptr or dereferencing it.
It's usually a sign of poor design for a library interface to take a
shared_ptr (but there are exceptions). Since the function you're
calling expects to take responsibility, or at least partial
responsibility, for the object you pass it, and the rest of the code
isn't prepared for this, you're only safe solution is to clone the
object, e.g.:
double x = f( boost::shared_ptr<Obj>( new Obj( object ) ) );
But you'd really be best off finding out why f requires a
shared_ptr, and why g can't take one as an argument.
How can I create in g() a boost::shared pointer that leaves my object alive at the end?
You can give the shared pointer a custom destructor that does nothing:
boost::shared_ptr<Obj> p(&object, [](void*){});
or if your compiler doesn't support lambdas:
void do_nothing(void*) {}
boost::shared_ptr<Obj> p(&object, do_nothing);
Even if I make it work do you think this way of doing is bad design?
Yes: you lose the lifetime management that shared pointers give you, and it is now your responsibility to make sure that the object outlives all of the shared pointers.
What is the best practice to solve this kind of problems?
Decide on an ownership model for all the objects you're using, and stick to it. Shared pointers can be useful when you want to share ownership, but not otherwise. In your case f wants to share ownership, and whatever calls g seems to want exclusive ownership; it would be a good idea to think about why they want that, and whether you can change one to be compatible with the other.
std::shared_ptr<T> is to possible give multiple entities ownership of the referenced object. If an interface expects a std::shared_ptr<T> there are two possibilities:
Someone ignorantly used std::shared_ptr<T> in an interface which was meant to receive a T object or a reference or a pointer to a T object. If that is the case the author shall be educated (and if this doesn't work be released from his current duties to pursue a new career) and the interface corrected.
Since now all interfaces using a std::shared_ptr<T> are using this to possibly grant shared ownership to the object, it should be obvious that a stack allocated T isn't a suitable argument to such an interface. The only possible argument is a T object whose life-time is maintained vy a std::shared_ptr<T>.
I realize that this doesn't answer the original question but it should be clear that the only viable course of action is: don't ever try to pass an object to a function taking a std::shared_ptr<T> which can't be fully controlled by such a pointer! (the same applies to the boost version of shared pointers).