Related
Based on this
Stroustrup suggests that "A pointer in a function should not represent ownership"
Question> Can someone give me a little detail explanation? Best if an example is illustrated.
Thank you
A pointer is "owned" by some code if that code is responsible for deleting it, or for transferring ownership to someone else. Various smart pointers implement explicit ownership models. shared_ptr represents multiple pieces of code owning a pointer. unique_ptr represents only one piece of code that owns the pointer.
What he's saying is that if a function has a naked pointer (a pointer not in a smart pointer), it should not be considered to own it. If it is to claim some ownership of this pointer, it should either have been given a smart pointer as a parameter, or it should have stored the pointer it created with new in a smart pointer.
He's saying that only smart pointers own pointers. If a function takes a naked pointer as a parameter, it does not claim ownership of that pointer. If a function returns a naked pointer, you cannot claim ownership of that pointer.
std::unique_ptr<int> pOwner(new int(5)); // this is the owner
int* pAccess = pOwner.get(); // this is a weak accessor, it does not own anything
He's talking about the role of raw pointers in a C++11 world. Owning pointers are meant to be shared_ptr and unique_ptr (they are the owners because they are responsible for deleting the object). Raw pointers should be used to access objects which are owned by a smart pointer. In C++11 you should basically never have a reason to explicitly call delete on a raw pointer anymore.
When you create a dynamic object using new, some other object will be responsible for deleting it once it is no longer needed; that object is the dynamic object's "owner".
If you were to always refer to the object using plain pointers, then it's difficult to tell (without documentation) which of those pointers pointers represents ownership. If you pass a pointer to a function, then does the function take ownership? Or is the caller still responsible for deleting it? If you get that wrong, then you'll either not delete it (causing a resource leak, which might degrade your program's performance and eventually stop it from working), or you might delete it too soon (which can cause all manner of bugs, often very hard to track down).
A widely-used solution for this is to have a policy of always using smart pointers (objects that look like pointers, but contain logic to manage their target's lifetime) to denote ownership, and to never delete anything to which you just have a plain pointer. Then there is never any confusion about whether or not to delete something. The standard library provides smart pointers (unique_ptr and shared_ptr) that give the common semantics of ownership by a single object, and ownership shared between multiple objects.
This is one aspect of the wider topic of resource management via RAII, which is extremely important in C++. As well as providing a clear ownership model, it is also the only sensible way to reliably prevent memory leaks when exceptions are thrown.
class B;
class A
{
public:
A ()
: m_b(new B())
{
}
shared_ptr<B> GimmeB ()
{
return m_b;
}
private:
shared_ptr<B> m_b;
};
Let's say B is a class that semantically should not exist outside of the lifetime of A, i.e., it makes absolutely no sense for B to exist by itself. Should GimmeB return a shared_ptr<B> or a B*?
In general, is it good practice to completely avoid using raw pointers in C++ code, in lieu of smart pointers?
I am of the opinion that shared_ptr should only be used when there is explicit transfer or sharing of ownership, which I think is quite rare outside of cases where a function allocates some memory, populates it with some data, and returns it, and there is understanding between the caller and the callee that the former is now "responsible" for that data.
Your analysis is quite correct, I think. In this situation, I also would return a bare B*, or even a [const] B& if the object is guaranteed to never be null.
Having had some time to peruse smart pointers, I arrived at some guidelines which tell me what to do in many cases:
If you return an object whose lifetime is to be managed by the caller, return std::unique_ptr. The caller can assign it to a std::shared_ptr if it wants.
Returning std::shared_ptr is actually quite rare, and when it makes sense, it is generally obvious: you indicate to the caller that it will prolong the lifetime of the pointed-to object beyond the lifetime of the object which was originally maintaining the resource. Returning shared pointers from factories is no exception: you must do this eg. when you use std::enable_shared_from_this.
You very rarely need std::weak_ptr, except when you want to make sense of the lock method. This has some uses, but they are rare. In your example, if the lifetime of the A object was not deterministic from the caller's point of view, this would have been something to consider.
If you return a reference to an existing object whose lifetime the caller cannot control, then return a bare pointer or a reference. By doing so, you tell the caller that an object exists and that she doesn't have to take care of its lifetime. You should return a reference if you don't make use of the nullptr value.
The question "when should I use shared_ptr and when should I use raw pointers?" has a very simple answer:
Use raw pointers when you do not want to have any ownership attached to the pointer. This job can also often be done with references. Raw pointers can also be used in some low level code (such as for implementing smart pointers, or implementing containers).
Use unique_ptr or scope_ptr when you want unique ownership of the object. This is the most useful option, and should be used in most cases. Unique ownership can also be expressed by simply creating an object directly, rather than using a pointer (this is even better than using a unique_ptr, if it can be done).
Use shared_ptr or intrusive_ptr when you want shared ownership of the pointer. This can be confusing and inefficient, and is often not a good option. Shared ownership can be useful in some complex designs, but should be avoided in general, because it leads to code which is hard to understand.
shared_ptrs perform a totally different task from raw pointers, and neither shared_ptrs nor raw pointers are the best option for the majority of code.
The following is a good rule of thumb:
When there is no transfer of shared ownership references or plain pointers are good enough. (Plain pointers are more flexible than references.)
When there is transfer of ownership but no shared ownership then std::unique_ptr<> is a good choice. Often the case with factory functions.
When there is shared ownership, then it is a good use case for std::shared_ptr<> or boost::intrusive_ptr<>.
It is best to avoid shared ownership, partly because they are most expensive in terms of copying and std::shared_ptr<> takes double of the storage of a plain pointer, but, most importantly, because they are conducive for poor designs where there are no clear owners, which, in turn, leads to a hairball of objects that cannot destroy because they hold shared pointers to each other.
The best design is where clear ownership is established and is hierarchical, so that, ideally, no smart pointers are required at all. For example, if there is a factory that creates unique objects or returns existing ones, it makes sense for the factory to own the objects it creates and just keep them by value in an associative container (such as std::unordered_map), so that it can return plain pointers or references to its users. This factory must have lifetime that starts before its first user and ends after its last user (the hierarchical property), so that users cannot possible have a pointer to an already destroyed object.
If you don't want the callee of GimmeB() to be able to extend the lifetime of the pointer by keeping a copy of the ptr after the instance of A dies, then you definitely should not return a shared_ptr.
If the callee is not supposed to keep the returned pointer for long periods of time, i.e. there's no risk of the instance of A's lifetime expiring before the pointer's, then raw pointer would be better. But even a better choice is simply to use a reference, unless there's a good reason to use an actual raw pointer.
And finally in the case that the returned pointer can exist after the lifetime of the A instance has expired, but you don't want the pointer itself extend the lifetime of the B, then you can return a weak_ptr, which you can use to test whether it still exists.
The bottom line is that there's usually a nicer solution than using a raw pointer.
I agree with your opinion that shared_ptr is best used when explicit sharing of resources occurs, however there are other types of smart pointers available.
In your precise case: why not return a reference ?
A pointer suggests that the data might be null, however here there will always be a B in your A, thus it will never be null. The reference asserts this behavior.
That being said, I have seen people advocating the use of shared_ptr even in non-shared environments, and giving weak_ptr handles, with the idea of "securing" the application and avoiding stale pointers. Unfortunately, since you can recover a shared_ptr from the weak_ptr (and it is the only way to actually manipulate the data), this is still shared ownership even if it was not meant to be.
Note: there is a subtle bug with shared_ptr, a copy of A will share the same B as the original by default, unless you explicitly write a copy constructor and a copy assignment operator. And of course you would not use a raw pointer in A to hold a B, would you :) ?
Of course, another question is whether you actually need to do so. One of the tenets of good design is encapsulation. To achieve encapsulation:
You shall not return handles to your internals (see Law of Demeter).
so perhaps the real answer to your question is that instead of giving away a reference or pointer to B, it should only be modified through A's interface.
Generally, I would avoid using raw pointers as far as possible since they have very ambiguous meaning - you might have to deallocate the pointee, but maybe not, and only human-read and -written documentation tells you what the case is. And documentation is always bad, outdated or misunderstood.
If ownership is an issue, use a smart pointer. If not, I'd use a reference if practicable.
You allocate B at constuction of A.
You say B shouldn't persist outside As lifetime.
Both these point to B being a member of A and a just returning a reference accessor. Are you overengineering this?
I found that the C++ Core Guidelines give some very useful hints for this question:
To use raw pointer(T*) or smarter pointer depends on who owns the object (whose responsibility to release memory of the obj).
own :
smart pointer, owner<T*>
not own:
T*, T&, span<>
owner<>, span<> is defined in Microsoft GSL library
here is the rules of thumb:
1) never use raw pointer(or not own types) to pass ownership
2) smart pointer should only be used when ownership semantics are intended
3) T* or owner designate a individual object(only)
4) use vector/array/span for array
5) To my undetstanding, shared_ptr is usually used when you don't know who will release the obj, for example, one obj is used by multi-thread
It is good practice to avoid using raw pointers, but you can not just replace everything with shared_ptr. In the example, users of your class will assume that it's ok to extend B's lifetime beyond that of A's, and may decide to hold the returned B object for some time for their own reasons. You should return a weak_ptr, or, if B absolutely cannot exist when A is destroyed, a reference to B or simply a raw pointer.
When you say: "Let's say B is a class that semantically should not exist outside of the lifetime of A"
This tells me B should logically not exist without A, but what about physically existing?
If you can be sure no one will try using a *B after A dtors than perhaps a raw pointer will be fine. Otherwise a smarter pointer may be appropriate.
When clients have a direct pointer to A you have to trust they'll handle it appropriately; not try dtoring it etc.
I have a set of objects in a vector of pointers to their baseclass held inside a manager:
std::vector<object*> objectVec;
Classes may wish to spawn one of these objects using the Add() method in the manager. The problem is that they then subsequently need to set or update these objects themselves. I've decided to have Add() return a pointer to the object itself, which is stored in whatever class has decided to spawn one. The problem is dealing with the case where the object behind that pointer may have been deleted.
Add looks like this:
object* ObjectManager::Add(object* obj)
{
objectVec.push_back(obj);
return objectVec.back();
}
and used like this:
objectptr = ObjectManager::OMan()->Add(new object());
Where objectptr is a member of whatever class has called the function. So should that particular object be deleted, the pointer returned by Add would point to rubbish.
Is it my responsibility to ensure that whateverclass::objectptr is always set to NULL if this object is deleted? Or can this be dealt with using some sort of smart pointer? The problem being that I don't need to use a smart pointer to deal with the possibility of a memory leak, but to deal with the case where the stored pointer has become invalid.
Please let me know if i've been unclear, or if the question is badly formed.
Any help would be greatly appreciated.
Yes, you can store smart ptr's instead of raw ptr's in your vector. In this case if somebody releases an object, it's not deleted until the last reference is not released (the one held in vector in your case). You can use boost::shared_ptr or std::shared_ptr (C++11).
If this is not what you want, you can use boost::weak_ptr to store references in your vector. weak_ptr doesn't increment reference counter so if somebody releases an object, it's get deleted, but reference (weak_ptr) stored in your vector allows you to check this.
You likely want weak_ptr and shared_ptr. shared_ptr is a general smart pointer class. weak_ptr is an observer of shared_ptr. When all the references of the shared_ptr go away, instances of weak_ptr "become null" and are easier to deal with than a pointer to a deleted object.
These classes come with Boost.
http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/shared_ptr.htm
http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm
And if I'm not mistaken, there are equivalents built into std namespace on compilers that implement newer C++0x standards. Visual C++ keeps has this built in.
http://blogs.msdn.com/b/vcblog/archive/2011/02/16/10128357.aspx
Oh shoot, looks like everyone else beat me to the answer...
Best is to forget this "manager" idea, but if you do or if you don't, the solution to shared ownership is the same as always, use boost::shared_ptr.
Or, with relatively new compiler, use std::shared_ptr.
Considering that with shared_ptr the ownership issue is taken care of already, then ask yourself, what is it that the "manager" manages?
Cheers & hth.,
Is it my responsibility to ensure that whateverclass::objectptr is always set to NULL if this object is deleted?
You're writing the class, so it's up to you to decide. This is a design decision and either choice is admissible, provided that you document it:
design the application
write the documentation/specification
write the code to matches the specification
Or can this be dealt with using some sort of smart pointer?
Using a smart pointer (strong or weak version) will help achieve whatever behavior you chose for the class. However, it will also strongly affect the client code. In the following code:
class Scene
{
// can't use this object in a call to `ObjectManager::Add()`,
// assuming it uses a smart pointer to deal with object lifetimes.
Object myLight;
};
The use cases for the ObjectManager class should be taken into consideration, on top of simplicity of implementation. Think "write once, use a lot".
Dangling pointers and memory leaks are two different issues, but a proper shared pointer can protect from both. For this particular case, I'd suggest boost::shared_ptr.
Use std::vector<boost::shared_ptr<BaseType>> for the vector type and also have the objects that hold the bare pointers now hold instead a boost::shared_ptr<BaseType>. This will ensure that the pointers will stay valid in the vector and in the objects as long as one of those objects still exist.
If you have differing requirements, you can use a boost::weak_ptr in one of the places holding the pointer (either the vector or the object).
Also, the object can hold a derived type instead of a base type (boost::shared_ptr<DerivedType>) and you can convert between them using boost::shared_static_cast.
Here is the documentation for all of these concepts.
I have a class that contains a vector of object pointers. I have a GetObject(..) function in that class that looks through the vector, finds the object desired, and returns a pointer to it. However, if the user of the class does a delete() on that returned pointer, my program will crash because the vector still has a pointer to that, now invalid, object. So, in my GetObject() class, I can return a const pointer, but that doesn't solve the problem because you can still delete the object. The object is mutable so I can't return a pointer to a const object. I suppose I could prevent deletion by returning a reference to the object but I have my function returning NULL if there is an error. I guess I can pass back the object reference via the parameters and then return and error number like this
//-1 on object on found. 0 for success. Object is passed back in
// the function parameter result.
int MyObject::GetObject(int object_id, Item& result)
Is this the best solution for such a situation?
The best way to solve this problem is to use a shared-ownership smart pointer like shared_ptr, which you can find in Boost, C++ TR1, and C++0x.
A smart pointer is a container that manages the lifetime of your dynamically allocated object for you. It takes responsibility for deleteing the object when you are done using it.
With a shared ownership smart pointer, you can have multiple smart pointers that all share ownership of the dynamically allocated object. A reference count is kept that keeps track of how many smart pointers have ownership of the object, and when the last owning smart pointer is destroyed, the dynamically allocated object is deleted.
It is extremely difficult to manage resources manually in C++, and it's very easy to write code that looks correct and works right most of the time but that is still not correct. By using smart pointers and other resource-owning containers (like the standard library containers), you no longer have to manage resource manually. It is significantly easier to write correct code when all of your resource management is automatic.
Automatic resource management in C++ is accomplished using a design pattern called Resource Acquisition is Initialization (RAII), which is arguably the most important design pattern you as a C++ programmer should become familiar with.
Anybody in your code could also try to de-reference NULL. You going to stop them doing that too? If your container owns the object, and you make this clear (returning a raw pointer is usually pretty clear or mention in docs), then anyone who deletes it, the result is their own fault. The only way that you could guarantee the prevention of the deletion of the object is to prevent the user from ever gaining a native reference or pointer - in which case they just can't access the object.
Who are clients of your class? If they are not your mortal enemies you could just ask them nicely not to delete the object. Otherwise, there will always be a way for "them" to mess you up.
Okay, one possible solution is to make destructor private. That will prevent everyone from deleting the object. But then the object has to delete itself (delete this) somehow, maybe through some function called DeletObjectButDontBlameMeIfAppCrashes. If the owner is some other class then you can set the destructor to protected and owner class as friend of this class.
You should return a reference to the object. There are two ways to handle the case when there is no object found.
First, you can use the Null Object Pattern in order to implement a special value for that case. That might not make sense for your case though.
The other way is to split it up into two methods, one which can be used to check if an appropriate element exists, and one to retrieve it.
Many STL-containers or algorithms implement both of these, either by returned a past-the-end iterator, or by having empty() returns false as a prerequisite of calling a method like front or back.
If you can use the boost libraries, smart pointers can be used to ensure that pointers stay valid. Essentially, each reference to a smart pointer increases its "use count" by 1. When the reset function is called on a reference, the reference goes away and the use counter decrements. As long as some object is still holding on to a smart pointer, the reference will be valid. Note that the other classes will be able to change what its pointing to, but can't delete it.
(My description deals mainly with smart pointers specifically - the different types of pointers vary a little, but the general idea remains the same).
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.