This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Objects: When should I use pointer or reference
I just came from Java and is new to C++. Over the course of a month, I managed to teach myself C++. I've coded some basic stuff here and there, and understand some of the concepts (Polymorphism, Virtual Functions etc). Although I know how Pointers work, I'm still having trouble knowing WHEN to use them.
I know that when you want to create something out on the heap using new, you have to use a pointer, but I fail to recognize other situations in which pointers and references should be used. Is there some sort of rule of thumb on when to use pointers I should know about? Like when should function parameters have & or * in them etc. Sorry for the noob question.
Same answer in other So question (http://stackoverflow.com/questions/7058339/c-when-to-use-references-vs-pointers):
Use reference wherever you can, pointers wherever you must.
Avoid pointers until you can't.
The reason is that pointers makes things harder to follow/read, less safe and far more dangerous manipulations than any other constructs.
So the rule of thumbs is to use pointers only if there is no other choice.
For example, returning a pointer to an object is a valid option when the function can return nullptr in some cases and it is assumed it will. That said, a better option would be to use something similar to boost::optional.
Another example is to use pointers to raw memory for specific memory manipulations. That should be hidden and localized in very narrow parts of the code, to help limit the dangerous part of the whole code base.
In your example, there is no point in using a pointer as parameter because :
if you provide nullptr as parameter, you're going in undefined-behaviour-land;
the reference attribute version don't allow (without easy to spot tricks) the problem with 1.
the reference attribute version is simpler to understand for the user : you have to provide a valid object, not something that could be null.
If the behaviour of the function would have to work with or without a given object, then using a pointer as attribute suggest that you can pass nullptr as parameter and it is fine for the function. That's a kind of contract between the user and the implementation code.
Use references as function arguments (simple, efficient, (mostly) safe).
Use pointers as non-owning members of objects (reassignment tends to make more sense with pointers than with references).
Use smart pointers for owning heap-allocated objects (and avoid heap allocation for most objects).
Pointers can also be used where nullptr is a desirable possible value for the pointer and in situations where you want to use pointer arithmetic.
Related
I'm having trouble getting things organized properly with smart pointers. Almost to the point that I feel compelled to go back to using normal pointers.
I would like to make it easy to use smart pointers throughout the program without having to type shared_ptr<...> every time. One solution I think of right away is to make a template class and add a typedef sptr to it so I can do class Derived : public Object < Derived > .. and then use Derived::sptr = ... But this obviously is horrible because it does not work with another class that is then derived from Derived object.
And even doing typedef shared_ptr<..> MyObjectPtr is horrible because then it needs to be done for each kind of smart pointer for consistency's sake, or at least for unique_ptr and shared_ptr.
So what's the standard way people use smart pointers? Because frankly I'm starting to see it as being too much hassle to use them. :/
So what's the standard way people use smart pointers?
Rarely. The fact that you find it a hassle to use them is a sign that you over-use pointers. Try to refactor your code to make pointers the exception, not the rule. shared_ptr in particular has its niche, but it’s a small one: namely, when you genuinely have to share ownership of a resource between several objects. This is a rare situation.
Because frankly I'm starting to see it as being too much hassle to use them. :/
Agreed. That’s the main reason not to use pointers.
There are more ways to avoid pointers. In particular, shared_ptr really only needs to spelled out when you actually need to pass ownership. In functions which don’t deal with ownership, you wouldn’t pass a shared_ptr, or a raw pointer; you would pass a reference, and dereference the pointer upon calling the function.
And inside functions you almost never need to spell out the type; for instance, you can (and should) simply say auto x = …; instead of shared_ptr<Class> x = …; to initialise variables.
In summary, you should only need to spell out shared_ptr in very few places in your code.
I have a lot of code that creates objects dynamically. So using pointers is necessary because the number of objects is not known from the start. An object is created in one subsystem, then stored in another, then passed for further processing to the subsystem that created it. So that I guess means using shared_ptr. Good design? I don't know, but it seems most logical to ask subsystem to create a concrete object that it owns, return a pointer to an interface for that object and then pass it for further processing to another piece of code that will interact with the object through it's abstract interface.
I could return unique_ptr from factory method. But then I would run into trouble if I need to pass the object for processing multiple times. Because I would still need to know about the object after I pass it to another method and unique_ptr would mean that I lose track of the object after doing move(). Since I need to have at least two references to the object this means using shared_ptr.
I heard somewhere that most commonly used smart pointer is unique_ptr. Certainly not so in my application. I end up with using shared_ptr mush more often. Is this a sign of bad design then?
In attempting to answer another question, I was intrigued by a bout of curiousity, and wanted to find out if an idea was possible.
Is it possible to dynamically dereference either a void * pointer (we assume it points to a valid referenced dynamically allocated copy) or some other type during run time to return the correct type?
Is there some way to store a supplied type (as in, the class knows the void * points to an int), if so how?
Can said stored type (if possible) be used to dynamically dereference?
Can a type be passed on it's own as an argument to a function?
Generally the concept (no code available) is a doubly-linked list of void * pointers (or similar) that can dynamically allocated space, which also keep with them a copy of what type they hold for later dereference.
1) Dynamic references:
No. Instead of having your variables hold just pointers, have them hold a struct containing both the actual pointer and a tag defining what type the pointer is pointing to
struct Ref{
int tag;
void *ref;
};
and then, when "dereferencing", first check the tag to find out what you want to do.
2) Storing types in your variables, passing them to functions.
This doesn't really make sense, as types aren't values that can be stored around. Perhaps what you just want is to pass around a class / constructor function and that is certainly feasible.
In the end, C and C++ are bare-bones languages. While a variable assignment in a dynamic language looks a lot like a variable assignment in C (they are just a = after all) in reality the dynamic language is doing a lot of extra stuff behind the scenes (something it is allowed to do, since a new language is free to define its semantics)
Sorry, this is not really possible in C++ due to lack of type reflection and lack of dynamic binding. Dynamic dereferencing is especially impossible due to these.
You could try to emulate its behavior by storing types as enums or std::type_info* pointers, but these are far from practical. They require registration of types, and huge switch..case or if..else statements every time you want to do something with them. A common container class and several wrapper classes might help achieving them (I'm sure this is some design pattern, any idea of its name?)
You could also use inheritance to solve your problem if it fits.
Or perhaps you need to reconsider your current design. What exactly do you need this for?
I'm currently doing my first real project in C++ and so, fairly new to pointers. I know what they are and have read some basic usage rules. Probably not enough since I still do not really understand when to use them, and when not.
The problem is that most places just mention that most people either overuse them or underuse them. My question is, when to use them, and when not?.
Currently, in many cases i'm asking myself, should I use a pointer here or just pass the variable itself to the function.
For instance, I know that you can send a pointer to a function so the function can actually alter the variable itself instead of a copy of it. But when you just need to get some information of the object once (for instance the method needs a getValue() something), are pointers usefull in that case?
I would love to see either reactions but also links that might be helpfull. Since it is my first time using C++ I do not yet have a good C++ book (was thinking about buying one if I keep on using c++ which I probably will).
For the do's and dont's of C++:
Effective C++ and More Effective C++ by Scott Meyers.
For pointers (and references):
use pass by value if the type fits into 4 Bytes and don't want to have it changed after the return of the call.
use pass by reference to const if the type is larger and you don't want to have it changed after the return of the call.
use pass by reference if the parameter can't be NULL
use a pointer otherwise.
dont't use raw pointers if you don't need to. Most of the time, a smart pointer (see Boost) is the better option.
From the c++ faq:
Use references when you can, and
pointers when you have to.
https://isocpp.org/wiki/faq/references#refs-vs-ptrs
1) I tend to use member variables scoped with the class. They are constructed in the initializer of the class, and I don't need to worry about pointers.
2) You can pass by reference to a function, and not worry about passing pointers. This effectively will pass a pointer to the method / function that can be used as if you passed the class, but without the overhead of copying the class itself.
3) If I need to control the lifetime of an object that is independent of my main application architecture's classes... then I will use an auto_ptr from the STL to automatically handle the pointer's destruction when no one longer references it. Check it out - it's the way to go.
Use it whenever you are dealing with allocated memory or passing arguments by reference to a method; I don't think there is a rule for not using pointers.
My rules of thumb:
Always pass function parameters as const references,
unless they are built-in types, in which case they are copied (and const/non-const becomes a question of style as the caller isn't affected) or
unless they are meant to be changed inside the function so that the changes reflect at the caller's, in which case they are passed by non-const reference or
unless the function should be callable even if callers don't have an object to pass, then they are passed as pointers, so that callers can pass in NULL pointers instead (apply #1 and #3 to decide whether to pass per const T* or per T*)
Streams must always be passed around as non-const references.
Generally, when you can use references instead of pointers it is a good idea. A reference must have a target (no NULL pointer violations), they allow the same semantics as pointers when being passed as arguments to a function, and they are generally nicer to use for beginners (or those not coming from a C background).
Pointers are required when you want to do dynamic allocation of memory; when you need to deal with an unknown amount of things that will be later specified. In this case the interface to access memory is through new and delete which deal in pointers.
My philosophy is to always pass by value, unless you need to modify the variable passed or copying the object is expensive. In both these cases, consider using a reference instead of a pointer first: if you don't need to change which object you're referencing, nor do you need a possible extremal value (NULL pointer), you can use a reference.
Don't forget about iterators either.
All good answers above. Additionally, if you are performing some processor-intensive work, it's important to realize that dereferencing a pointer will likely be a cache miss on your processor. It's a good idea to keep your data accessible with minimal pointer dereferences.
Class attribute: pointer
Variables declared in methods: no pointers, so we avoid memory leaks.
In this way, prevent memory leaks and controlle attribute's consistency.
Salu2.
Do smart pointers handle down casting, and if not what is a safe way of working around this limitation?
An example of what I'm trying to do is having two STL vectors (for example) containing smart pointers. The first contains smart pointers to a base class while the second contains smart pointers to a derived class. The smart pointers are referenced counted, e.g. similar behaviour to Boost's shared_ptrs, but hand-rolled. I've included some sample code that I whipped up to provide an example:
vector<CBaseSmartPtr> vecBase;
vector<CDerivedSmartPtr> vecDer;
...
CBaseSmartPtr first = vecBase.front();
vecDer.push_back(CDerivedSmartPtr(dynamic_cast<CDerived*>(first.get()));
This seems not safe to me, as I think I'm ending up with two smart pointers managing the same object. At some point down the track this is probably going to result in one of them freeing the object while the other still holds references to it.
What I'd hope for but don't think will work is a straight down-cast while keeping the same object, e.g.
dynamic_cast<CDerivedSmartPtr>(first)
Should I be looking to change the second container to also use CBaseSmartPtr and downcast on usage only? Are there other solutions?
Smart pointers can handle downcasting, but it's not automatic. And getting const-correctness in can be a bit complex (I've used our smart pointer implementation in interview questions, there's some template trickery involved). But many users of smart pointers never instantiate their smart pointers with const-qualified types anyway.
The first thing you need to get correct is the counter. Since you may need to share a counter between smart_ptr<Base> and smart_ptr<Derived>, the counter type should not depend on the type argument. In general, this is not a big deal anyway. A counter is merely a size_t, probably wrapped in a class. (Note: there are alternative smart pointer designs, but the question strongly suggests a counter is used)
A cast towards base should be fairly trivial. Hence, your smart_ptr should have a constructor taking a smart_ptr. In this ctor, add a line static_cast<T*>((U*)0);. This doesn't generate code, but prevents instantiation when T is not a base of U (modulo const qualifications).
The other way around should be an explicit cast. You can't programatically enumerate all bases of T, so smart_ptr<T> cannot derive from smart_ptr<Base1_of_T>, smart_ptr<Base2_of_T>, ... Hence, a dynamic_cast<smart_ptr<T> > won't work. You can provide your own smart_dynamic_cast<SPT>(smart_ptr<U> const& pU). This is best implemented as a function returing an SPT. In this function, you can simply do a return SPT(dynamic_cast<SPT::value_type*>(&*pU)).
The property you want is covariance in the pointed-to type. That is, if D isa B, then you want smartptr<D> isa smartptr<B>. I don't think this is elegantly supported at all in C++, but as always, there are template/overload hacks available.
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/pointer_cast.html gives a dynamic cast that works on regular and boost::smart_ptr. You should learn from the implementation if you don't want to just use Boost's.
Follow the thread here in one of the boost mailing lists. It shows how one can implement smart-pointer downcasting in case of boost::shared_ptr. HTH
Normal smart pointers, like std::auto_ptr, are not safe to use in STL containers, due to ownership being moved around when the STL assigns instances of smart pointers to each other as it copies data around internally. You need to use something like boost::shared_ptr instead, which internally implements reference counting to ensure an object stays alive no matter how many smart pointer instances refer to it. If you are writing your own smart pointer types, then you need to implement similar reference counting.
I've found this on Microsoft pages:
std::shared_ptr<base> sp0(new derived);
std::shared_ptr<derived> sp1 =
std::dynamic_pointer_cast<derived>(sp0);
I've been evaluating various smart pointer implementations (wow, there are a LOT out there) and it seems to me that most of them can be categorized into two broad classifications:
1) This category uses inheritance on the objects referenced so that they have reference counts and usually up() and down() (or their equivalents) implemented. IE, to use the smart pointer, the objects you're pointing at must inherit from some class the ref implementation provides.
2) This category uses a secondary object to hold the reference counts. For example, instead of pointing the smart pointer right at an object, it actually points at this meta data object... Who has a reference count and up() and down() implementations (and who usually provides a mechanism for the pointer to get at the actual object being pointed to, so that the smart pointer can properly implement operator ->()).
Now, 1 has the downside that it forces all of the objects you'd like to reference count to inherit from a common ancestor, and this means that you cannot use this to reference count objects that you don't have control over the source code to.
2 has the problem that since the count is stored in another object, if you ever have a situation that a pointer to an existing reference counted object is being converted into a reference, you probably have a bug (I.E., since the count is not in the actual object, there is no way for the new reference to get the count... ref to ref copy construction or assignment is fine, because they can share the count object, but if you ever have to convert from a pointer, you're totally hosed)...
Now, as I understand it, boost::shared_pointer uses mechanism 2, or something like it... That said, I can't quite make up my mind which is worse! I have only ever used mechanism 1, in production code... Does anyone have experience with both styles? Or perhaps there is another way thats better than both of these?
"What is the best way to implement smart pointers in C++"
Don't! Use an existing, well tested smart pointer, such as boost::shared_ptr or std::tr1::shared_ptr (std::unique_ptr and std::shared_ptr with C++ 11)
If you have to, then remember to:
use safe-bool idiom
provide an operator->
provide the strong exception guarantee
document the exception requirements your class makes on the deleter
use copy-modify-swap where possible to implement the strong exception guarantee
document whether you handle multithreading correctly
write extensive unit tests
implement conversion-to-base in such a way that it will delete on the derived pointer type (policied smart pointers / dynamic deleter smart pointers)
support getting access to raw pointer
consider cost/benifit of providing weak pointers to break cycles
provide appropriate casting operators for your smart pointers
make your constructor templated to handle constructing base pointer from derived.
And don't forget anything I may have forgotten in the above incomplete list.
Just to supply a different view to the ubiquitous Boost answer (even though it is the right answer for many uses), take a look at Loki's implementation of smart pointers. For a discourse on the design philosophy, the original creator of Loki wrote the book Modern C++ Design.
I've been using boost::shared_ptr for several years now and while you are right about the downside (no assignment via pointer possible), I think it was definitely worth it because of the huge amount of pointer-related bugs it saved me from.
In my homebrew game engine I've replaced normal pointers with shared_ptr as much as possible. The performance hit this causes is actually not so bad if you are calling most functions by reference so that the compiler does not have to create too many temporary shared_ptr instances.
Boost also has an intrusive pointer (like solution 1), that doesn't require inheriting from anything. It does require changing the pointer to class to store the reference count and provide appropriate member functions. I've used this in cases where memory efficiency was important, and didn't want the overhead of another object for each shared pointer used.
Example:
class Event {
public:
typedef boost::intrusive_ptr<Event> Ptr;
void addRef();
unsigned release();
\\ ...
private:
unsigned fRefCount;
};
inline void Event::addRef()
{
fRefCount++;
}
inline unsigned Event::release(){
fRefCount--;
return fRefCount;
}
inline void intrusive_ptr_add_ref(Event* e)
{
e->addRef();
}
inline void intrusive_ptr_release(Event* e)
{
if (e->release() == 0)
delete e;
}
The Ptr typedef is used so that I can easily switcth between boost::shared_ptr<> and boost::intrusive_ptr<> without changing any client code
If you stick with the ones that are in the standard library you will be fine.
Though there are a few other types than the ones you specified.
Shared: Where the ownership is shared between multiple objects
Owned: Where one object owns the object but transfer is allowed.
Unmovable: Where one object owns the object and it can not be transferred.
The standard library has:
std::auto_ptr
Boost has a couple more than have been adapted by tr1 (next version of the standard)
std::tr1::shared_ptr
std::tr1::weak_ptr
And those still in boost (which in relatively is a must have anyway) that hopefully make it into tr2.
boost::scoped_ptr
boost::scoped_array
boost::shared_array
boost::intrusive_ptr
See:
Smart Pointers: Or who owns you baby?
It seems to me this question is kind of like asking "Which is the best sort algorithm?" There is no one answer, it depends on your circumstances.
For my own purposes, I'm using your type 1. I don't have access to the TR1 library. I do have complete control over all the classes I need to have shared pointers to. The additional memory and time efficiency of type 1 might be pretty slight, but memory usage and speed are big issues for my code, so type 1 was a slam dunk.
On the other hand, for anyone who can use TR1, I'd think the type 2 std::tr1::shared_ptr class would be a sensible default choice, to be used whenever there isn't some pressing reason not to use it.
The problem with 2 can be worked around. Boost offers boost::shared_from_this for this same reason. In practice, it's not a big problem.
But the reason they went with your option #2 is that it can be used in all cases. Relying on inheritance isn't always an option, and then you're left with a smart pointer you can't use for half your code.
I'd have to say #2 is best, simply because it can be used in any circumstances.
Our project uses smart pointers extensively. In the beginning there was uncertainty about which pointer to use, and so one of the main authors chose an intrusive pointer in his module and the other a non-intrusive version.
In general, the differences between the two pointer types were not significant. The only exception being that early versions of our non-intrusive pointer implicitly converted from a raw pointer and this can easily lead to memory problems if the pointers are used incorrectly:
void doSomething (NIPtr<int> const &);
void foo () {
NIPtr<int> i = new int;
int & j = *i;
doSomething (&j); // Ooops - owned by two pointers! :(
}
A while ago, some refactoring resulted in some parts of the code being merged, and so a choice had to be made about which pointer type to use. The non-intrusive pointer now had the converting constructor declared as explicit and so it was decided to go with the intrusive pointer to save on the amount of code change that was required.
To our great surprise one thing we did notice was that we had an immediate performance improvement by using the intrusive pointer. We did not put much research into this, and just assumed that the difference was the cost of maintaining the count object. It is possible that other implementations of non-intrusive shared pointer have solved this problem by now.
What you are talking about are intrusive and non-intrusive smart pointers. Boost has both. boost::intrusive_ptr calls a function to decrease and increase the reference count of your object, everytime it needs to change the reference count. It's not calling member functions, but free functions. So it allows managing objects without the need to change the definition of their types. And as you say, boost::shared_ptr is non-intrusive, your category 2.
I have an answer explaining intrusive_ptr: Making shared_ptr not use delete. In short, you use it if you have an object that has already reference counting, or need (as you explain) an object that is already referenced to be owned by an intrusive_ptr.