Assume that I want to write function that takes in a pointer. However I want to allow caller to use naked pointers or smart pointers - whatever they prefer. This should be good because my code should rely on pointer semantics, not how pointers are actually implemented. This is one way to do this:
template<typename MyPtr>
void doSomething(MyPtr p)
{
//store pointer for later use
this->var1 = p;
//do something here
}
Above will use duck typing and one can pass naked pointers or smart pointers. The problem occurs when passed value is base pointer and we need to see if we can cast to derived type.
template<typename BasePtr, typename DerivedPtr>
void doSomething(BasePtr b)
{
auto d = dynamic_cast<DerivedPtr>(b);
if (d) {
this->var1 = d;
//do some more things here
}
}
Above code will work for raw pointers but won't work for the smart pointers because I need to use dynamic_pointer_cast instead of dynamic_cast.
One solution to above problem is that I add new utility method, something like, universal_dynamic_cast that works both on raw pointers and smart pointers by selecting overloaded version using std::enable_if.
The questions I have are,
Is there a value in adding all these complexities so code supports raw as well as smart pointers? Or should we just use shared_ptr in our library public APIs? I know this depends on purpose of library, but what is the general feeling about using shared_ptr all over API signatures? Assume that we only have to support C++11.
Why doesn't STL has built-in pointer casts that are agnostic of whether you pass raw pointers or smart pointers? Is this intentional from STL designers or just oversight?
One other problem in above approach is loss of intellisense and bit of readability. This is the problem obviously in all duck typed code. In C++, however, we have a choice. I could have easily strongly typed my argument above like shared_ptr<MyBase> which would sacrifice flexibility for callers to pass whatever wrapped in whatever pointer but reader of my code would be more confident and can build better model on on what should be coming in. In C++ public library APIs, are there general preferences/advantages one way or another?
There is one more approach I have seen in other SO answer where the author proposed that you should just use template<typename T> and let caller decide if T is some pointer type or reference or class. This super generic approach obviously don't work if I have to call something in T because C++ requires dereferencing pointer types which means I have to probably create utility method like universal_deref using std::enable_if that applies * operator to pointer types but does nothing for plain objects. I wonder if there are any design patterns that allows this super generic approach more easily. Again, above all, is it worth going all these troubles or just keep thing simple and use shared_ptr everywhere?
To store a shared_ptr within a class has a semantic meaning. It means that the class is now claiming ownership of that object: the responsibility for its destruction. In the case of shared_ptr, you are potentially sharing that responsibility with other code.
To store a naked T*... well, that has no clear meaning. The Core C++ Guidelines tell us that naked pointers should not be used to represent object ownership, but other people do different things.
Under the core guidelines, what you are talking about is a function that may or may not claim ownership of an object, based on how the user calls it. I would say that you have a very confused interface. Ownership semantics are usually part of the fundamental structure of code. A function either takes ownership or it does not; it's not something that gets determined based on where it gets called.
However, there are times (typically for optimization reasons) where you might need this. Where you might have an object that in one instance is given ownership of memory and in another instance is not. This typically crops up with strings, where some users will allocate a string that you should clean up, and other users will get the string from static data (like a literal), so you don't clean it up.
In those cases, I would say that you should develop a smart pointer type which has this specific semantics. It can be constructed from a shared_ptr<T> or a T*. Internally, it would probably use a variant<shared_ptr<T>, T*> or a similar type if you don't have access to variant.
Then you could give it its own dynamic/static/reinterpret/const_pointer_cast functions, which would forward the operation as needed, based on the status of the internal variant.
Alternatively, shared_ptr instances can be given a deleter object that does nothing. So if your interface just uses shared_ptr, the user can choose to pass an object that it technically does not truly own.
The usual solution is
template<typename T>
void doSomething(T& p)
{
//store reference for later use
this->var1 = &p;
}
This decouples the type I use internally from the representation used by the caller. Yes, there's a lifetime issue, but that's unavoidable. I cannot enforce a lifetime policy on my caller and at the same time accept any pointer. If I want to ensure the object stays alive, I must change the interface to std::shared_ptr<T>.
I think the solution you want is to force callers of your function to pass a regular pointer rather than using a template function. Using shared_ptrs is a good practice, but provides no benefit in passing along the stack, since the object is already held in a shared pointer by the caller of your function, guaranteeing it does not get destroyed, and your function isn't really "holding on" to the object. Use shared_ptrs when storing as a member (or when instantiating the object that will become stored in a member), but not when passing as an argument. It should be a simple matter for the caller to get a raw pointer from the shared_ptr anyway.
The purpose of smart pointers
The purpose of smart pointers is to manage memory resources. When you have a smart pointer, then you usually claim unique or shared ownership. On the other hand, raw pointers just point to some memory that is managed by someone else. Having a raw pointer as a function parameter basically tells the caller of the function that the function is not caring about the memory management. It can be stack memory or heap memory. It does not matter. It only needs to outlive the lifetime of the function call.
Semantics of pointer parameters
When passing a unique_ptr to a function (by value), then your passing the responsibility to clean up memory to that function. When passing a shared_ptr or weak_ptr to a function, then that's saying "I'll possibly share memory ownership with that function or object it belongs to". That's quite different from passing a raw pointer, which implicitly mean "Here's a pointer. You can access it until you return (unless specified otherwise)".
Conclusion
If you have a function, then you usually know which kind of ownership semantics you have and 98% of the time you don't care about ownership and should just stick to raw pointers or even just references, if you know that the pointer you're passing is not a nullptr anyways. Callers that have smart pointers can use the p.get() member function or &*p, if they want to be more terse. Therefore, I would not recommend to template code to tackle your problem, since raw pointers give the caller all the flexibility you can get. Avoiding templates also allows you to put your implementation into an implementation file (and not into a header file).
To answer your concrete questions:
I don't see much value in adding this complexity. To the contrary: It complicates your code unnecessarily.
There is hardly any need for this. Even if you use std::dynamic_pointer_cast in the such, it is to maintain ownership in some way. However, adequate uses of this are rare, because most of the time just using dynamic_cast<U*>(ptr.get()) is all you need. That way you avoid the overhead of shared ownership management.
My preference would be: Use raw pointers. You get all the flexibility, intellisense and so forth and you will live happily ever after.
I would rather call this an antipattern - a pattern that should not be used. If you want to be generic, then use raw pointers (if they are nullable) or references, if the pointer parameter would never be a nullptr. This gives the caller all the flexibility while keeping the interface clean and simple.
Further reading: Herb Sutter talked about smart pointers as function parameters in his Guru of the Week #91. He explains the topic in depth there. Especially point 3 might be interesting to you.
After reviewing some more material, I've finally decided to use plain old raw pointers in my public interface. Here is the reasoning:
We shouldn't be designing interface to accommodate bad design decisions of others. The mantra of "avoid raw pointers like a plague and replace them with smart pointers everywhere" is just bad advice (also se Shutter's GoTW). Trying to support those bad decisions spreads them in to your own code.
Raw pointers explicitly sets up contract with callers that they are the one who need to worry about lifetime of inputs.
Raw pointers gives the maximum flexibility to callers who have shared_ptr, unique_ptr or just raw pointers.
Code now looks much more readable, intuitive and reasonable unlike those duck typed templates taking over everywhere.
I get my strong typing back along with intellisense and better compile time checks.
Casting up and down hierarchy is a breeze and don't have to worry about perf implications where new instance of smart pointer may get created at each cast.
While passing pointers around internally, I don't have to carefully care if the pointer would be shared_ptr or raw pointer.
Although I don't care about it, there is better pathway to support older compilers.
In short, trying to accommodate potential clients who have taken up on guidelines of never using raw pointers and replace them with smart pointers everywhere causes polluting my code with unnecessary complexity. So keep simple things simple and just use raw pointers unless you explicitly want ownership.
Related
Are there any reasons to still use raw pointers (for managed resources) in C++11/14?
Should resource member variables in a class be held in their own smart pointers for automatic RAII without need for cleanup in destructor?
Is the implementation of smart pointers inlined that there is no overhead in doing so?
Are there any reasons to still use raw pointers (for managed
resources) in C++11/14?
I assume that by "managed resources" you mean "owned resources".
Yes there are reasons:
As you are inferring in your question, sometime you want to refer to an object or none, and it can change through time. You have to use a raw pointer in this case, because there is no alternative right now in this specific case. There might be later as there is a proposal about adding a "dumb" non-owning pointer which just clarify the role of the pointer (observe/refer, not own). Meanwhile the recommendation is to avoid new/delete if you can and use raw pointer only as "refers to without owning" kind of re-assignable reference.
You still need raw pointers for implementation of non-raw pointers and any low level RAII construct. Not everybody needs to work on fundamental libraries, but of course if you do, then you need basic constructs to work with. For example in my domain I often have to build up custom "object pool" systems in different ways. At some point in the implementation you have to manipulate raw memory which are not objects yet, so you need to use raw pointers to work with that.
When communicating with C interfaces, you have no other choices than to pass raw pointers to functions taking them. A lot of C++ developers have to do this, so it's just in some very specific regions of your code that you will have to use them.
Most companies using C++ don't have a "modern C++" experience of C++ and work with code that use a lot of pointers where it is not actually necessary. So most of the time when you add code to their codebase, you might be forced by the code-environment, politics, peer-pressure and conventions of the company to use pointers where in a more "modern c++" usage kind of company it would not pass peer-review. So consider the political/historic/social/knowledge-base-of-coworkers context too when choosing your techniques. Or make sure companies/projects you work in match your way of doing things (this might be harder).
Should resource member variables in a class be held in their own smart
pointers for automatic RAII without need for cleanup in destructor?
Resource member variables, in the best case, should just be members without being obvious pointers, not even smart pointers. Smart pointers are a "bridge" between code manipulating raw pointers and pure RAII style. If you have total control over some code and it's new code, you can totally avoid making any use of smart pointer in your interfaces. Maybe you will need them in your implementations though. Keep in mind that there is no actual rules, only recommendations of what you could result in if you
Is the implementation of smart pointers inlined that there is no
overhead in doing so?
Implementation of standard smart pointers is as efficient as they can be so yes most of their code is inlined. However, they are not always free, it depends on what they actually do. For example, in almost all cases, unique_ptr is exactly one raw pointer, with just additional checks around it's places of use. So it's "free". shared_ptr on the other hand have to maintain a counter of how many other shared_ptr refer to the same object. That counter can be changed on several threads doing copies of the shared_ptr, so it have to be atomic. Changing the value of atomic counters is not always free, and you should always assume that there is a higher cost than copying a raw pointer.
So "it depends".
Just:
use RAII as much as you can, without exposing any kind of pointer in your interfaces (smart or not);
use standard smart pointers in implementations if you must use owning pointers;
use raw pointers only if you need to refer to object, null, or other objects changing through time, without owning them;
avoid raw pointers in interfaces except in case of allowing passing optional objects (when nullptr is a correct argument);
You will end-up with code that, from the user's perspective, don't seem to manipulate pointers. If you have several layers of code following these rules, the code will be easier to follow and highly maintainable.
On a related note from: When to use references vs. pointers
Avoid pointers until you can't.
Also note that Sean Parents in his recent talks also consider smart pointers to be raw pointers. They can indeed be encapsulated as implementation details of value-semantic types corresponding to the actual concept being manipulated. Additionally using type-erasure techniques in implementations but never exposing them to the user helps extensibility of some library constructs.
It depends. If the object is fully owned, constructed and destructed by another object, there is a good case for using an std::unique_ptr in that other object. If you have an object which owns several such objects, all of which are dynamically allocated in the constructor, then you have to do something; if the semantics of the usual smart pointers isn't appropriate (which is often the case), then you'll have to invent something: in the case of a graph, for example, you might put the root pointer in a base class (initializing it to null), and have the destructor of the base class clean-up the graph, starting at the root.
Of course, unless your class has some sort of dynamic structure like a graph, you might ask yourself why it is using dynamic allocation to begin with. There are special cases (where, for example, the owned object is polymorphic, and its actual type depends on arguments to the constructor), but in my experience, they aren't that common. In practice, there just aren't that many cases where a smart pointer can be used in an object, much less should be used.
RAII is more than just wrapping up new and delete - a smart pointer is a form of RAII but RAII is a lot more than that. A good candidate for RAII is when you have any sort of mirroring functions: new/delete, initialise/teardown, stop/start. So your resource should still have its own RAII class - one that performs its cleanup function in its own destructor.
More and more I hear, that I should use smart pointers instead of naked pointers, despite I have effective memory leak system implemented.
What is the correct programming approach on using smart pointers please? Should they really be used, even if I check memory leaks on allocated memory blocks? Is it still up to me? If I do not use them, can this be considered as programming weakness?
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
You should use RAII to handle all resource allocations.
Smart pointers are just one common special case of that rule.
And smart pointers are more than just shared_ptr. There are different smart pointers with different ownership semantics. Use the one that suits your needs. (The main ones are scoped_ptr, shared_ptr, weak_ptr and auto_ptr/unique_ptr (prefer the latter where available). Depending on your compiler, they may be available in the standard library, as part of TR1, or not at all, in which case you can get them through the Boost libraries.
And yes, you should absolutely use these. It costs you nothing (if done correctly, you lose zero performance), and it gains you a lot (memory and other resources are automatically freed, and you don't have to remember to handle it manually, and your code using the resource gets shorter and more concise)
Note that not every pointer usage represents some kind of resource ownership, and so not all raw pointer usage is wrong. If you simply need to point to an object owned by someone else, a raw pointer is perfectly suitable. But if you own the object, then you should take proper ownership of it, either by giving the class itself RAII semantics, or by wrapping it in a smart pointer.
You can't just blindly substitute std::auto_ptr for every raw pointer. In particular, auto_ptr transfers ownership on assignment, which is great for some purposes but definitely not for others.
There is a real reason there are several varieties of smart pointers (e.g., shared_ptr, weak_ptr, auto_ptr/unique_ptr, etc.) Each fulfills a different purpose. One major weakness of a "raw" pointer is that it has so many different uses (and has that versatility largely because it does little or nothing to assist in any one purpose). Smart pointers tend to be more specialized, which means they can be more intelligent about doing one thing well, but also means you have to pick the right one for the job or it'll end up dong the wrong things entirely.
Smart pointers allows to define automatically the life-time of objects it refers to. That's the main thing to understand.
So, no, you shouldn't use smart pointers everywhere, only when you want to automate life-time of your objects instead of having, for example, an object managing those objects inside from birth to death. It's like any tool : it solves specific kind of problems, not all problems.
For each object, you should think about the life cycle it will go through, then choose one of the simplest correct and efficient solution. Sometimes it will be shared_ptr because you want the object to be used by several components and to be automatically destroyed once not used anymore. Sometimes you need the object only in the current scope/parent-object, so scoped_ptr might be more appropriate. Sometimes you need only one owner of the instance, so unique_ptr is appropriate. Maybe you'll find cases where you know an algorithm that might define/automate the lifetime of an object, so you'll write your own smart pointer for it.
For example of opposite case, using pools forbids you to use smart_ptr. Naked pointers might be a more welcome simple and efficient solution in this particular (but common in embedded software) case.
See this answer (from me) for more explainations : https://softwareengineering.stackexchange.com/questions/57581/in-c-is-it-a-reflection-of-poor-software-design-if-objects-are-deleted-manuall/57611#57611
Should they really be used, even if I check memory leaks on allocated memory blocks?
YES
The whole purpose of smart pointers is, it help you implement RAII(SBRM), which basically lets the resource itself take the responsibility of its deallocation and the resource doesn't have to rely on you explicitly remembering to deallocate it.
If I do not use them, can this be considered as programming weakness?
NO,
It is not a weakness but a inconvenience or unnecessary hassle to explicitly manage the resources by yourself if you are not using Smart pointers(RAII). The purpose of smart pointers to implement RAII is to provide efficient and hassle free way of handling resources and you would just not be making use of it if you are not using it. It is highly recommended to use it purely for the numerous advantages it provides.
If the smart pointers(ex: std::auto_ptr)are strongly recommended, should I use them instead of every naked pointer?
YES
You should use smart pointers wherever possible because simply there is no drawback of using them and just numerous advantages to use them.
Don't use auto_ptr though because it is already deprecated!! There are various other smart pointers available that you can use depending on the requirement. You can refer the link above to know more about them.
It's a tricky question, and the fact that there is currently a mode to
use smart pointers everywhere doesn't make things any easier. Smart
pointers can help in certain situations, but you certainly can't just
use them everywhere, without thinking. There are many different types
of smart pointers, and you have to think about which one is appropriate
in every case; and even then, most of your pointers (at least in typical
applications in the domains I've worked in) should be raw pointers.
Regardless of the approach, several points are worth mentionning:
Don't use dynamic allocation unless you have to. In many
applications, the only things that need to be allocated dynamically
are objects with specific lifetimes, determined by the application
logic. Don't use dynamic allocation for objects with value semantics.
With regards to entity object, those which model something in the
application domain: these should be created and destructed according
to the program logic. Irregardless of whether there are pointers to
them or not. If their destruction causes a problem, then you have an
error in your program logic somewhere (not handling an event correctly,
etc.), and using smart pointers won't change anything.
A typical example of an entity object might be client connection in a
server, is created when the client connects, and destructed when the
client disconnects. In many such cases, the most appropriate management
will be a delete this, since it is the connection which will receive
the disconnection event. (Objects which hold pointers to such an object
will have to register with it, in order to be informed of its
destruction. But such pointers are purely for navigation, and shouldn't
be smart pointers.)
What you'll usually find when people try to use smart pointers
everywhere is that memory leaks; typical reference counters don't
handle cycles, and of course, typical applications are full of cycles: a
Connection will point to the Client which is connected to it, and
the Client will contain a list of Connection where it is connected.
And if the smart pointer is boost::shared_ptr, there's also a definite
risk of dangling pointers: it's far to easy to create two
boost::shared_ptr to the same address (which results in two counters
for the references).
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
In my opinion, yes, you should it for every pointer that you own.
Here are my ideas on resource management in C++ (feel free to disagree):
Good resource management requires thinking in terms of ownership.
Resources should be managed managed by objects (RAII).
Usually single ownership is preferred over shared ownership.
Ideally the creator is also the owner of the object. (However, there are situations where ownership transfer is in order.)
This leads to the following practices:
Make boost::scoped_ptr the default choice for local and member variables. Do keep in mind that using scoped_ptr for member variables will make your class non-copyable. If you don't want this see next point.
Use boost::shared_ptr for containers or to enable shared ownership:
// Container of MyClass* pointers:
typedef boost::shared_ptr<MyClass> MyClassPtr;
std::vector<MyClassPtr> vec;
The std::auto_ptr (C++03) can be used for ownership transfer. For example as the return value of factory or clone methods:
// Factory method returns auto_ptr
std::auto_ptr<Button> button = Button::Create(...);
// Clone method returns auto_ptr
std::auto_ptr<MyClass> copy = obj->clone();
// Use release() to transfer the ownership to a scoped_ptr or shared_ptr
boost::scoped_ptr<MyClass> copy(obj->clone().release());
If you need to store a pointer that you don't own then you can use a raw pointer:
this->parent = inParentObject;
In certain situations a boost::weak_pointer is required. See the documentation for more information.
In general you should prefer smart pointers, but there are a couple of exceptions.
If you need to recast a pointer, for example to provide a const version, that becomes nearly impossible with smart pointers.
Smart pointers are used to control object lifetime. Often when you are passing a pointer to a function, the function will not affect the lifetime; the function does not try to delete the object, and it does not store a copy of the pointer. The calling code cannot delete the object until the function returns. In that case a dumb pointer is perfectly acceptable.
Yes. Assuming you have C++0x available to you, use unique_ptr or shared_ptr (as appropriate) to wrap all the raw pointers you new up. With the help of make_shared, shared_ptr is highly performant. If you don't need reference counting then unique_ptr will get you better perf. Both of them behave properly in collections and other circumstances where auto_ptr was a dumb pointer.
Using smart pointers (shared_ptr or otherwise) EVERYWHERE is a bad idea. It's good to use shared_ptr to manage the lifetime of objects/resources but it's not a good idea to pass them as parameters to functions etc. That increases the likelihood of circular references and other extremely hard to track bugs (Personal experience: Try figuring out who should not be holding onto a resource in 2 millions lines of code if every function invocation changes the reference count - you will end up thinking the guys who do this kind of thing are m***ns). Better to pass a raw pointer or a reference.
The situation is even worse when combined with lazy instantiation.
I would suggest that developers should know the lifecycle of the objects they write and use shared_ptr to control that (RAII) but not extend shared_ptr use beyond that.
A newbie question: I have a hierarchy of classes with some virtual functions and I am trying to implement a factory method, but I am not sure what is the best way:
Return a raw pointer from the factory method and wrap it into a smart pointer in the calling method
Return a smart pointer from the factory
Return a proper object from the factory (but is it going to copy the derived class correctly?) and assign it to a local object in the calling method
Return a reference from the factory (but how to create the object in the factory method without a memory leak?)
I would be grateful for an example of a factory method and a minimal client, which is effective and doesn't leak memory.
My background is C# and Java, so I am a bit lost with memory management in C++ atm.
Options 3 and 4 are out from the start because they simply don’t work: 3 slices the object, 4 creates memory leaks or invalid references.
From the other two methods, I strongly prefer 2: return a smart pointer. In fact, strive to avoid raw pointers completely, if possible. Unfortunately, C++ makes this a lot to write (and this is not a trivial objection! Anybody who has ever written object-oriented code in C++ and has used smart pointers throughout shares my pain) – but the alternative is even more pain.
Of course, there is alternative 5: use raw pointers and a garbage collector.
well my taste go to returning a smart pointer. here is a link to an example Abstract factory that returns a smart pointer.
my2c
I prefer method 1 because it's more flexible. However, whether you return the raw pointer or the smart pointer is really just a matter of object usage. For example, you might want to return a raw pointer because you know that the object will sometimes be used once and immediately deleted in the same code block. In that case, there is no need to incur the overhead of contructing a smart pointer object. But if the lifetime of the object is always uncertain and you're worried about memory leaks, then by all means use method 2. Methods 3 and 4 are incorrect.
You need memory management, there is no other viable choice. However you may not need memory management from within the factory method.
The main issue with smart pointers is their absence of covariance, which is pain when implementing a clone virtual method. Unfortunately the covariance rule is not relaxed in C++0x so it remains an issue.
On the other hand, returning a raw pointer and leaving it up to the caller to wrap it up, is opening the door to bugs (even though it's the approach Boost elected for its clones).
Personally, I would suggest:
the infamous auto_ptr or a plain pointer that the caller should wrap in C++03
a unique_ptr as soon as your compiler gets it
The latter combine most advantages (leaving covariance aside), and includes little to no performance overhead.
After having struggled with method 1, I can assure you that method 2, either returning boost::shared_ptr or boost::scoped_ptr (usually the former is what you want, if you don't have access to std::unique_ptr) is what I wholeheartedly recommand.
What is the best practice when returning a smart pointer, for example a boost::shared_ptr? Should I by standard return the smart pointer, or the underlying raw pointer? I come from C# so I tend to always return smart pointers, because it feels right. Like this (skipping const-correctness for shorter code):
class X
{
public:
boost::shared_ptr<Y> getInternal() {return m_internal;}
private:
boost::shared_ptr<Y> m_internal;
}
However I've seen some experienced coders returning the raw pointer, and putting the raw pointers in vectors. What is the right way to do it?
There is no "right" way. It really depends on the context.
You can internally handle memory with a smart pointer and externally give references or raw pointers. After all, the user of your interface doesn't need to know how you manage memory internally. In a synchronous context this is safe and efficient. In an asynchronous context, there are many pitfalls.
If you're unsure about what to do you can safely return smart pointers to your caller. The object will be deallocated when the references count reaches zero. Just make sure that you don't have a class that keeps smart pointers of objects for ever thus preventing the deallocation when needed.
As a last note, in C++ don't overuse dynamically allocated objects. There are many cases where you don't need a pointer and can work on references and const references. That's safer and reduces the pressure on the memory allocator.
It depends on what the meaning of the pointer is.
When returning a shared_pointer, you are syntactically saying "You will share ownership of this object", such that, if the the original container object dies before you release your pointer, that object will still exist.
Returning a raw pointer says: "You know about this object, but don't own it". It's a way of passing control, but not keeping the lifetime tied to the original owner.
(in some older c-programs, it means "It's now your problem to delete me", but I'd heavily recommend avoiding this one)
Typically, defaulting to shared saves me a lot of hassle, but it depends on your design.
I follow the following guidelines for passing pointers arguments to functions and returning pointers:
boost::shared_ptr
API and client are sharing ownership of this object. However you have to be careful to avoid circular references with shared_ptr, if the objects represent some kind of graph. I try to limit my use of shared_ptr for this reason.
boost::weak_ptr / raw pointer
API owns this object, you are allowed share it while it is valid. If there is a chance the client will live longer than the api I use a weak_ptr.
std::auto_ptr
API is creating an object but the client owns the object. This ensures that the returning code is exception safe, and clearly states that ownership is being transferred.
boost::scoped_ptr
For pointers to objects stored on the stack or as class member variables. I try to use scoped_ptr first.
Like all guidelines there will be times when the rules conflict or have to be bent, then I try to use intelligence.
I typically return "owning"/"unique" smart pointers from factories or similar to make it clear who is responsible for cleaning up.
This example https://ideone.com/qJnzva shows how to return a std::unique_ptr that will be deleted when the scope of the variable that the caller assigns the value to goes out of scope.
While it's true that the smart pointer deletes its own pointer, the lifetime of the variable holding the smart pointer is 100% controlled by the caller, so the caller decides when the pointer is deleted. However, since it's a "unique" and "owning" smart pointer, no other client can control the lifetime.
I would never return a raw pointer, instead I would return a weak_ptr to tell the user of the pointer that he doesn't have the control over the resource.
If you return a weak_ptr its very unlikely that there will be dangling pointers in the application.
If there is a performance problem I would return a reference to the object and a hasValidXObject method.
In my opinion, in C++, you should always have to justify the use of an unguarded pointer.
There could be many valid reasons: a need for very high performance, for very low memory usage, for dealing with legacy libraries, because of some issue with the underlying data structure the pointer is storing. But [dynamically allocated] pointers are somewhat 'evil', in that you have to deallocate the memory at every possible execution path and you will almost certainly forget one.
I wouldn't put raw pointers in vectors.
In case they use auto_ptr or boost::scoped_ptr, they can't use (or return) anything but raw pointers. That could explain their way of coding, i guess.
depends on your goals.
blindly returning smart ptr to internal data might not be a good idea (which is very sensitive to the task you're trying to solve) - you might be better off just offering some doX() and doY() that use the pointer internally instead.
on the other hand, if returning the smart ptr, you should also consider that you'll create no mutual circular references when objects end up unable to destroy each other (weak_ptr might be a better option in that case).
otherwise, like already mentioned above, performance/legacy code/lifetime considerations should all be taken into account.
const boost::shared_ptr &getInternal() {return m_internal;}
This avoids a copy.
Sometimes you'll like to return a reference, for example:
Y &operator*() { return *m_internal; }
const Y &operator*() const { return *m_internal; }
This is good too only if the reference will be used and discarded inmediately.
The same goes for a raw pointer.
Returning a weak_ptr is also an option.
The 4 are good depending on the goals. This question requires a more extensive discussion.
In a C++ project that uses smart pointers, such as boost::shared_ptr, what is a good design philosophy regarding use of "this"?
Consider that:
It's dangerous to store the raw pointer contained in any smart pointer for later use. You've given up control of object deletion and trust the smart pointer to do it at the right time.
Non-static class members intrinsically use a this pointer. It's a raw pointer and that can't be changed.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to make a shared pointer to my class.
Given that, when is it ever appropriate for me to explicitly use a this pointer? Are there design paradigms that can prevent bugs related to this?
Wrong question
In a C++ project that uses smart pointers
The issue has nothing to do with smart pointers actually. It is only about ownership.
Smart pointers are just tools
They change nothing WRT the concept of ownership, esp. the need to have well-defined ownership in your program, the fact that ownership can be voluntarily transferred, but cannot be taken by a client.
You must understand that smart pointers (also locks and other RAII objects) represent a value and a relationship WRT this value at the same time. A shared_ptr is a reference to an object and establishes a relationship: the object must not be destroyed before this shared_ptr, and when this shared_ptr is destroyed, if it is the last one aliasing this object, the object must be destroyed immediately. (unique_ptr can be viewed as a special case of shared_ptr where there is zero aliasing by definition, so the unique_ptr is always the last one aliasing an object.)
Why you should use smart pointers
It is recommended to use smart pointers because they express a lot with only variables and functions declarations.
Smart pointers can only express a well-defined design, they don't take away the need to define ownership. In contrast, garbage collection takes away the need to define who is responsible for memory deallocation. (But do not take away the need to define who is responsible for other resources clean-up.)
Even in non-purely functional garbage collected languages, you need to make ownership clear: you don't want to overwrite the value of an object if other components still need the old value. This is notably true in Java, where the concept of ownership of mutable data structure is extremely important in threaded programs.
What about raw pointers?
The use of a raw pointer does not mean there is no ownership. It's just not described by a variable declaration. It can be described in comments, in your design documents, etc.
That's why many C++ programmers consider that using raw pointers instead of the adequate smart pointer is inferior: because it's less expressive (I have avoided the terms "good" and "bad" on purpose). I believe the Linux kernel would be more readable with a few C++ objects to express relationships.
You can implement a specific design with or without smart pointers. The implementation that uses smart pointer appropriately will be considered superior by many C++ programmers.
Your real question
In a C++ project, what is a good design philosophy regarding use of "this"?
That's awfully vague.
It's dangerous to store the raw pointer for later use.
Why do you need to a pointer for later use?
You've given up control of object deletion and trust the responsible component to do it at the right time.
Indeed, some component is responsible for the lifetime of the variable. You cannot take the responsibility: it has to be transferred.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to use my class.
Obviously, since the caller is not informed that the function will hide a pointer and use it later without the control of the caller, you are creating bugs.
The solution is obviously to either:
transfer responsibility to handle the lifetime of the object to the function
ensure that the pointer is only saved and used under the control of the caller
Only in the first case, you might end up with a smart pointer in the class implementation.
The source of your problem
I think that your problem is that you are trying hard to complicate matters using smart pointers. Smart pointers are tools to make things easier, not harder. If smart pointers complicate your specification, then rethink your spec in term of simpler things.
Don't try to introduce smart pointers as a solution before you have a problem.
Only introduce smart pointers to solve a specific well-defined problem. Because you don't describe a specific well-defined problem, it is not possible to discuss a specific solution (involving smart pointers or not).
While i don't have a general answer or some idiom, there is boost::enable_shared_from_this . It allows you to get a shared_ptr managing an object that is already managed by shared_ptr. Since in a member function you have no reference to those managing shared_ptr's, enable_shared_ptr does allow you to get a shared_ptr instance and pass that when you need to pass the this pointer.
But this won't solve the issue of passing this from within the constructor, since at that time, no shared_ptr is managing your object yet.
One example of correct use is return *this; in functions like operator++() and operator<<().
When you are using a smart pointer class, you are right that is dangerous to directly expose "this". There are some pointer classes related to boost::shared_ptr<T> that may be of use:
boost::enable_shared_from_this<T>
Provides the ability to have an object return a shared pointer to itself that uses the same reference counting data as an existing shared pointer to the object
boost::weak_ptr<T>
Works hand-in-hand with shared pointers, but do not hold a reference to the object. If all the shared pointers go away and the object is released, a weak pointer will be able to tell that the object no longer exists and will return you NULL instead of a pointer to invalid memory. You can use weak pointers to get shared pointers to a valid reference-counted object.
Neither of these is foolproof, of course, but they'll at least make your code more stable and secure while providing appropriate access and reference counting for your objects.
If you need to use this, just use it explicitly. Smart pointers wrap only pointers of the objects they own - either exclusivelly (unique_ptr) or in a shared manner (shared_ptr).
I personally like to use the this pointer when accessing member variables of the class. For example:
void foo::bar ()
{
this->some_var += 7;
}
It's just a harmless question of style. Some people like it, somepeople don't.
But using the this pointer for any other thing is likely to cause problems. If you really need to do fancy things with it, you should really reconsider your design. I once saw some code that, in the constructor of a class, it assigned the this pointer to another pointer stored somewhere else! That's just crazy, and I can't ever think of a reason to do that. The whole code was a huge mess, by the way.
Can you tell us what exactly do you want to do with the pointer?
Another option is using intrusive smart pointers, and taking care of reference counting within the object itself, not the pointers. This requires a bit more work, but is actually more efficient and easy to control.
Another reason to pass around this is if you want to keep a central registry of all of the objects. In the constructor, an object calls a static method of the registry with this. Its useful for various publish/subscribe mechanisms, or when you don't want the registry to need knowledge of what objects/classes are in the system.