6

Possible Duplicate:
Which kind of pointer do I use when?

There are many pros in favour of C++11's smart pointers: They are safer, they're functionality and scope is more abvious etc.

Are the "classic" C like pointers

class C{};
C c;
C* c_p = &c;

obsolete now? Are they even deprecated? Or are there use cases where C pointers still make sense?

edit: The code snippet with a smart pointer:

class C{};
C c;
std::shared_ptr<C> c_p(new C());

edit: Thanks for pointing out the duplicate. From Xeo's answer there:

Use dumb pointers (raw pointers) or references for non-owning references to resources and when >you know that the resource will outlive the referencing object / scope. Prefer references and >use raw pointers when you need either nullability or resettability.

If that's all that there is, I accept that this question has been closed.

Community
  • 1
  • 1
steffen
  • 8,572
  • 11
  • 52
  • 90

3 Answers3

14

There are use cases where raw pointers make sense.

Raw pointers in modern code are 'non-owning' pointers. This means the code shouldn't do anything that requires or takes ownership of the pointed to object. For example it shouldn't be deleted, used to construct an owning smart pointer, or saved beyond the current context.

bames53
  • 86,085
  • 15
  • 179
  • 244
  • 1
    The role of non-owning, reassignable references can now be filled by `std::reference_wrapper`, though I admit I've never used it. – Benjamin Lindley Jul 23 '12 at 07:42
  • 1
    @barnes53: That's what raw pointers should *not* do... What *should* they do? – steffen Jul 23 '12 at 08:04
  • 2
    @steffen Didn't you get the answer or was this a joke? He's not advising you not to do certain things with raw pointers, he's advising you to **use** raw pointers in certain situation, namely when you **don't do** certain things with the pointed to object. – Christian Rau Jul 23 '12 at 08:27
  • @steffen the list is things that shouldn't be done with non-owning pointers, not things that shouldn't be done with raw pointers. What you should do with a raw pointer is use it as a non-owning pointer. (and the things you should do with a non-owning pointer are test against nullptr and derefernce it to use the pointed-to object) – bames53 Jul 23 '12 at 08:32
  • 'test against nullptr': I can avoid this by using a smart pointer. 'derefernce it': That's what I would do with any pointer. In other words: In which cases is it preferable to use raw pointers? – steffen Jul 23 '12 at 08:48
  • @steffen the standard smart pointers can be null, so you still test them. It's preferable to use a raw pointer when you want a pointer but you don't want to pass ownership with it. I.e. when you need a non-owning pointer. – bames53 Jul 23 '12 at 14:10
  • @barnes53: Sorry to insist. When I want a non-owning pointer, I will use a `std::weak_ptr`. Or not? – steffen Jul 24 '12 at 14:47
  • @steffen weak_ptr is the non-owning counterpart to shared_ptr only, using a raw pointer could be considered the non-owning counterpart to unique_ptr. – bames53 Jul 24 '12 at 15:10
8

Absolutely not. The smart pointers are for special cases, not for general use. Depending on the application and programming style, most pointers will still be raw pointers; in some cases, in fact, there may be no smart pointers at all.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 2
    I respectfully disagree. For someone who needs to ask, most pointers will probably have to be smart pointers. (The few remaining ones can be considered random-access iterators.) – sbi Jul 23 '12 at 07:51
  • 1
    I would say that 'default' pointer would now be the 'std::unique_ptr'. Most of the time, you pointer represents data that is owned – thecoshman Jul 23 '12 at 07:58
  • 2
    If someone needs to ask, then the standard smart pointers will only cause more problems. In practice, in most applications, _most_ pointers are for navigation, and should not be smart pointers. They can't be `unique_ptr`, because there will be numerous pointers to the same object, and they can't be `shared_ptr`, because there will be cycles. And most objects will have a lifetime determined by the application; otherwise, they probably shouldn't be allocated dynamically to begin with. Which means that smart pointers won't do the right thing anyway. – James Kanze Jul 23 '12 at 08:23
  • @thecoshman You must have an unusual application. Why would you dynamically allocate owned data to begin with? – James Kanze Jul 23 '12 at 08:24
  • let's say you are making a game, you dynamically create a 'monster' object, you would probably want that to be 'owned' by a monster controller. Something like a spawner, may want a weak_ptr to it, so that it can keep track of how many monsters *it* has spawned that are still alive, so it knows if it should make more. Contrived example I'll admit, but not so far fetched – thecoshman Jul 23 '12 at 10:06
  • @thecoshman If you're making a game (where you don't have to worry about issues like transactional integrity), an object of type `Monster` will almost certainly do a `delete this` at some point, say when its hit points drop below a certain level. There is _no_ place for the usual smart pointers here. – James Kanze Jul 23 '12 at 12:55
  • @JamesKanze but something like 'spell effects' that the monster has, are owned by the monster object and thus should be done via smart pointers. Yes, you could just use raw pointers, but if you are going to stick to out date methods, what hope is there – thecoshman Jul 23 '12 at 14:58
  • @thecoshman Things that are owned by the monster are probably best handled by aggregation, rather than pointers. (Of course, if they're polymorphic, you need dynamic allocation, and in that case, `std::unique_ptr` may be the way to go.) – James Kanze Jul 23 '12 at 16:17
  • @James: "...most pointers are for navigation..." See, I alreadfy said so: "The few remaining ones can be considered random-access iterators." This is not what most users (especially newbies) think about when they think pointers. – sbi Jul 23 '12 at 22:26
  • @JamesKanze: Most dynamically allocated objects will be stored in some kind of container, and for those it's perfectly fine to be smart pointers. – sbi Jul 23 '12 at 22:27
  • It's more then perfectly fine, it's preferable. By avoiding raw pointers (which you may not always be able to do) you avoid having to concern your self with such low level memory management. The more automatic you memory is handled, the easier your code is to maintain. – thecoshman Jul 24 '12 at 07:37
  • @sbi I can't remember the last time I had a container which owned any pointed to objects. About the only time this would make sense is when there is some form of polymorphism, and polymorphic objects are typically entity objects, with a defined lifetime, independently of the container. – James Kanze Jul 29 '12 at 15:19
  • @JamesKanze: Then maybe either me or you have a weird application area. Lots of code I have seen over the last decade or two creates polymorphic objects which then need to be stored somewhere. – sbi Jul 29 '12 at 18:38
  • @JamesKanze: _"Until the learner really understands raw pointers, and how they are used, they shouldn't be introduced to smart pointers..."_ Oddly enough, to that I fully agree. However, I do not believe users have to _use_ raw pointers in order to understand the usefulness of smart pointer. For years, I have taught C++ to students who knew Java, and I only ever _explained_ the perils of manual resource management, which was enough to make them gladly embrace smart pointers. – sbi Jul 29 '12 at 18:42
  • _"...which are only used in special cases anyway"_ Well, if you would be kind enough to look to the beginning of this comment discussion, you will find that I disagreed with that premise from the very beginning. It's against all my experience. – sbi Jul 29 '12 at 18:42
  • @sbi Most of the polymorphic objects I've dealt with have been entity objects, which have a lifetime determined by the program specifications, and not by whether they happen to be in some container. (The destructor of such objects may remove them from a number of different containers. But it is the destruction which triggers the removal, and not vice versa.) – James Kanze Jul 30 '12 at 07:58
  • @JamesKanze I am confused as to what your perspective is here. Yes, for a person new to C++ and the notion of pointers, the four types might seem a bit confusing. But a more experienced developer should know and understand the subtle differences, and know when you use each type. However, to take this back to the original debate, your statement that people should use raw pointers by default is, at the very least, questionable. If some needs to ask what type they need, I push them towards unique_ptr unless there is some other information that would change this, such as requiring shared access – thecoshman Jul 30 '12 at 09:29
  • @thecoshman `unique_ptr` doesn't work in most of the cases where you need pointers. Nor does `shared_ptr` (because most cases where pointers are needed involve cycles). – James Kanze Jul 30 '12 at 15:07
  • @JamesKanze (╯°□°)╯︵ ┻━┻ – thecoshman Jul 30 '12 at 15:10
4

No, raw pointers are not obsolete. Their use is usually discouraged unless necessary. Maintaining ownership of an object via a raw pointer is discouraged even more, since you have to remember to delete it, which may be hard in the presence of exceptions.

Raw pointers are somewhat more efficient than smart pointers, so their use makes sense in some performance-sensitive parts of the code. In some fields, such as linear algebra, pointer arithmetic can be useful, and you'd use raw pointers there [1], or build new abstractions on top of raw pointers, possibly in combination with smart pointers, rather than using only smart pointers.

[1] E.g. for defining a view of a submatrix

Oleg2718281828
  • 1,039
  • 7
  • 17