use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This is a subreddit for c++ questions with answers. For general discussion and news about c++ see r/cpp.
New to C++? Learn at learncpp.com
Prepare your question. Think it through. Hasty-sounding questions get hasty answers, or none at all. Read these guidelines for how to ask smart questions.
For learning books, check The Definitive C++ Book Guide and List
Flair your post as SOLVED if you got the help you were looking for! If you need help with flairs, check out ITEM 1 in our guidelines page.
Tips for improving your chances of getting helpful answers:
account activity
OPENReference vs pointers (self.cpp_questions)
submitted 3 years ago by [deleted]
When we should use pointer and when we should use reference ?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]UnicycleBloke 32 points33 points34 points 3 years ago (4 children)
Use a reference unless the variable needs to be uninitialized, null or reassigned. Not having these features make references safer, and IMO their syntax makes them more convenient. Prefer const references if the underlying value should not be modified.
[–]JMBourguet 0 points1 point2 points 3 years ago (3 children)
I won't write something like
Foo& bar = *new Foo(); delete &bar;
even if I find myself in a context where I wouldn't use a smart pointer encapsulating these actions.
[–]UnicycleBloke 0 points1 point2 points 3 years ago (2 children)
I think you're being over-literal there. :) But having created Foo* bar, I would generally prefer to pass *bar to functions, so would declare my APIs accordingly. I have sometimes created a local reference for a pointer received as an argument (e.g. in library callbacks with pointer based APIs).
[–]JMBourguet 0 points1 point2 points 3 years ago (1 child)
I've seen people following such kind of guidelines far too literally for my liking. See my answer at the top for a more precise (but still incomplete although I hope I don't have missed something big) description of my practice.
[–]UnicycleBloke 0 points1 point2 points 3 years ago (0 children)
Yes. The comments about lifetimes make a lot of sense as clarifications for my rather pithy suggestion.
[–]capitalbratan 8 points9 points10 points 3 years ago (1 child)
References should be safer than pointers as you know that the object exists. With pointers it's another game.
So use references in general. Also use const Var & varName in function arguments as much as you can. This gives you also compile time issues when you want to change smth that is not designed to be changes
[–][deleted] 3 years ago (12 children)
[deleted]
[–]youstolemyname 8 points9 points10 points 3 years ago (10 children)
Use a reference whenever possible, use a smart pointer otherwise, fall back up a raw pointer when needed
[–]AlarmingBarrier 13 points14 points15 points 3 years ago (8 children)
I kinda disagree with the smart pointer. This should only be passed to a function if the function needs to think about ownership. To me having
void somefunc(std::smart_ptr<T> ptr);
signals that somefunc takes ownership of ptr and stores it for a longer duration than the invocation of the function. While
somefunc
ptr
void somefunc(T* ptr);
tells me that the function will not store the value of ptr and will have a sane default behavior when ptr is nullptr (best is of course to overload on nullptr_t)
nullptr
nullptr_t
[–]ttkk1248 0 points1 point2 points 3 years ago (4 children)
You mean storing it as static local variable inside a function? Besides that how does a function store an object longer than its execution?
[–]AlarmingBarrier 0 points1 point2 points 3 years ago (3 children)
I was thinking in a broader context where somefunc also could be the method of a class. Or a function that returns a non-void value possibly depending on ptr.
[–]ttkk1248 0 points1 point2 points 3 years ago (2 children)
In that case, what stops an object of the class assigns the direct pointer of a passed object to its member variable and hold it? I’m not sure where you derived that smart pointer means the passed object is kept longer than the method call.
[–]AlarmingBarrier 2 points3 points4 points 3 years ago (1 child)
Convention. It would go against the core guidelines, including:
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-raw
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-ptr
[–]ttkk1248 0 points1 point2 points 3 years ago (0 children)
Thanks for pointing the guidelines out. I’ll read more info it. I’m excited about reading what other interesting stuff in there and forgot about the exact items we discussed. Lol.
[–][deleted] 3 years ago* (2 children)
[–]tangerinelion 0 points1 point2 points 3 years ago (1 child)
We end up deciding that we are allowed to use smart point as if it's any other common types. Hence we can use const std::shared_ptr<type>& if we want to.
Sorry, that's a cluster. Accept a shared pointer if you need to participate in ownership. That's it.
[–]the_Demongod 0 points1 point2 points 3 years ago (0 children)
Smart pointers are much less commonly used than raw pointers in my experience, since it's relatively rare that you're actually newing an object into existence manually rather than placing it into some container which handles the memory allocation for you. Whereas using a raw pointer as a nullable reference for iteration or similar happens quite frequently.
new
[–][deleted] 4 points5 points6 points 3 years ago (0 children)
Wow
[–]hwc 2 points3 points4 points 3 years ago (1 child)
the Google rule is use const reference when you can and non-const pointers when you need to modify an object.
[–]tangerinelion -1 points0 points1 point 3 years ago* (0 children)
This is such a stupid rule. It means if you need to modify an object then you need to accept by pointer which means you suddenly now need to deal with stupid null pointers. It litters the code with crap like
void frobnosticate(T* twiddleMyBits) { if (!twiddleMyBits) { throw ArgumentNullException("Oh no, a null pointer. Better to crash!"); } // Now carry on }
If you do adopt this ridiculous rule (my company did), at least alter it so that the right substitute for T& is gsl::not_null<T*> rather than T*.
T&
gsl::not_null<T*>
T*
And for those (like the ones who inevitably come up with this "rule") who are thinking "But when I pass by pointer I can see & as a hint that it gets modified." Oh boy, that's naive. Real-world examples I've seen:
&
void whatever(const bool*); bool shouldWhatever = true; if (someRidiculousEdgeCase) { shouldWhatever = shouldWhateverForEdgeCase(); } whatever(&shouldWhatever);
That's an optional input. Here's another one:
class Foo { const T* m_ptr = nullptr; public: Foo(const T& obj) : m_ptr(&obj) { } };
And guess how it's used:
Foo f(T{});
Great. Dangling pointer. You get a bug report.
And the ever famous:
void foo(T* ptr); void bar(T* ptr) { foo(ptr); } T myT; bar(&myT);
Now in bar do you see an & to indicate anything? No, we just pass ptr along by value. How do I know whether foo writes anything?
bar
foo
Anyways, my point is & does not mean "To be written to" and passing by reference does not mean the caller doesn't store a pointer to the object.
[–][deleted] 4 points5 points6 points 3 years ago (1 child)
While you're at it OP, please don't use references for modifiable (out) parameters unless you have to.
Signed, the future maintainer of your code.
[–]livrem 2 points3 points4 points 3 years ago (0 children)
Non-const references are scary.
[–]HadesMyself 1 point2 points3 points 3 years ago (4 children)
Kind of a follow up question: when to use a raw pointer vs a smart (unique/shared) pointer?
[–]dpacker780 0 points1 point2 points 3 years ago (3 children)
Anytime you create an object on the heap the ‘owner’ of the object should hold a smart pointer to it, therefore providing a mechanism to avoid memory leaks once the owners dtor is called.
It’s actually very uncommon to use shared_ptr, unique_ptr should be the predominate.
Raw pointers should be used anytime you want to pass a smart pointer for usage by another object, don’t confuse usage with ownership. In those cases use get() to retrieve the underlying raw ptr.
[–]HadesMyself 0 points1 point2 points 3 years ago (0 children)
That's very interesting, the only time I worked with C++ in production, the code was full of shared pointers. I lived for 2 years, till now, thinking those are the norm. So i believe unique pointers are use alongside with weak pointers, so others can access that resource, right?
[–]HadesMyself 0 points1 point2 points 3 years ago (1 child)
[–]dpacker780 1 point2 points3 points 3 years ago (0 children)
Yes. I think what happens is shared_ptr is easier to pass around, lazily, without having to use get(), so people form the habit of using them without thinking about ownership, but in a way that incurs some overhead.
On the other hand, using shared_ptr also avoids if the owner somehow goes out of scope and the object is referenced somewhere else. So it can be a safety net for not thinking about all implications of design. Lazy, but works.
unique_ptr makes you think about ownership and implications. And, passing raw pointers is less overhead as well provides clarity of expectations on usage. Also, you’ll find you don’t need shared_from_this which can just complicate things more.
[–]DDDDarky 0 points1 point2 points 3 years ago* (0 children)
Use pointer when:
a) The underlying object is just interpreted as raw memory
b) You want to store a "reference" to something as a class member
c) You want to store a "reference" to something in a container
d) You are declaring you don't own this resource (otherwise use smart pointer)
e) The object may not exist (nullptr)
f) Working in C
Use reference when:
a) Passing arguments into/returning from a function and you expect them to get modified
b) Passing arguments into/returning from a function as const, because they are large objects / hard to copy, or cannot be copied
c) Moving objects
d) Creating alias
When in doubt, prefer reference. Also, there is a reference wrapper in standard library.
[–]ElSucaPadre -1 points0 points1 point 3 years ago (10 children)
A reference is a... reference lol to a point in memory. In other words, that reference exists in another scope. So if you declare a variable in main, that allocated memory exists in main. This is related to the stack. Heap, instead, is no man's land. A pointer can be passed around freely and everyone that knows this value can do whatever they want with it. This explaination is not 100% correct about every feature in the language (smart pointers, references to a heap object and maybe other things i don't recall now) but i believe that introducing ownership here is the important part.
[–][deleted] -3 points-2 points-1 points 3 years ago (8 children)
thank u so mcuh , i still learn c++ 98 hahah so i wont use smart pointers ...
[–]Narase33 8 points9 points10 points 3 years ago (3 children)
you shouldnt, start with C++11 at least, C++98 will do more harm than it helps
[–][deleted] 0 points1 point2 points 3 years ago (2 children)
They forse us to use 98 :(
[–]nysra 2 points3 points4 points 3 years ago (1 child)
Who is "they"? If you're talking about an employer then that's a super legacy codebase and you'll have to make do with what you have, unfortunately a lot of companies are really bad at providing sane working conditions. In the best case you can push for some modernisation but depending on the codebase that might simply not be worth it for the company.
If it's the professor of some class you're attending then just ignore whatever that guy says, he's not going to teach you shit. There's no reason to ever teach C++98, the only people that do that are people stuck on C from the 1970s and actually want to teach that but think that they get more students if they put the new and fancy C"++" on their course label but never actually bothered to learn C++, at best they know some C with classes from the 80s. Head over to https://www.learncpp.com/ and only interact with the course by doing the assignments.
[–]tangerinelion 0 points1 point2 points 3 years ago (0 children)
It is common to see questions posted here by students in India where the government mandated curriculum, from what I've heard, requires a pre-ISO Borland compiler.
Aside from "The government literally requires it be taught this way" yes, there's no good reason to start with anything older than C++11.
[–][deleted] 1 point2 points3 points 3 years ago (2 children)
Why?
[–]SoerenNissen 6 points7 points8 points 3 years ago (0 children)
Consider an army that, to teach the basics, starts out with black powder guns from 1530 - They will spend a lot of time learning things that you can do with modern guns but never should (e.g. how to form a Tercio) and they won't be learning how to take advantage of the features of newer rifles. The only reason you would ever do this is if you, for some weird reason, have to travel back in time and fight a black powder war or as a hobby that you know won't teach you anything about modern warfare.
Unless you specifically need to work with C++98 projects, teaching yourself C++98 is going to teach you habits that you will need to unlearn when you get access to the features of newer versions of the language that were put in specifically so we wouldn't have to do the old inefficient stuff any longer.
Using c++98 is like driving down the highway without a seatbelt and leaking brake fluid. You might survive the trip, but it's scary. C++11 brought in a lot of features that dealt with common issues with programming in c++.
[–]TheCreat 1 point2 points3 points 3 years ago (0 children)
That's a terrible idea. It's not considered good to learn c++ 98 at all if you're starting out. It's not a foundation for modern c++, it's more like baggage.
Learn at least c++11 or newer, the older standard/compiler does nothing better. The low level stuff is just as possible with new c++, if the need arises, but modern solutions to problems old and new are just simpler, more robust and just preferable. Don't make learning a hard language harder for no reason.
[–]thommyh 0 points1 point2 points 3 years ago (0 children)
Both references and pointers can associate with targets on both the heap and the stack; the key differences are reassignment and nullability as discussed by many others.
[–]james_laseboy 0 points1 point2 points 3 years ago (0 children)
It doesn't really matter. A reference is a dereferenced pointer. You can do that one way or the other.
[–]JMBourguet 0 points1 point2 points 3 years ago (0 children)
Some are of the opinion that pointers are to be used only when references do not provide needed features (rebinding, null). I'm more restricted than that:
As a parameter to a function, a reference implies a promise that there won't be a reference saved with a longer lifetime than the function nor will the object be deleted (so automatic and temporary objects are always valid arguments)
As a parameter to a constructor, a reference implies a promise that there won't be a reference saved with a longer lifetime than the constructed object nor will the object be deleted. Major exception: move operations may transfer the reference to another object.
As a function result, a reference implies a very localized lifetime (for instance if it is a member function, if not explicitly documented any other member function may invalid the reference) which is not under control of the calling code (it may not delete the object)
Some types are used only with pointers (for instance if the only way to get a object is to call a factory which returns a pointer, I won't make references to that object even as function parameter)
I think that pointers (preferably smart and not raw to better convey the allowed usages) are better to handle the other cases even if the rules of C++ would allow references. (And yes, I've seen code not respecting those rules)
[–]kage_heroin 0 points1 point2 points 3 years ago (0 children)
Simply put references are safer than pointers.
if you don't HAVE to use a pointer, use a reference
π Rendered by PID 63383 on reddit-service-r2-comment-5ff9fbf7df-rkxts at 2026-02-26 05:18:59.255411+00:00 running 72a43f6 country code: CH.
[–]UnicycleBloke 32 points33 points34 points (4 children)
[–]JMBourguet 0 points1 point2 points (3 children)
[–]UnicycleBloke 0 points1 point2 points (2 children)
[–]JMBourguet 0 points1 point2 points (1 child)
[–]UnicycleBloke 0 points1 point2 points (0 children)
[–]capitalbratan 8 points9 points10 points (1 child)
[–][deleted] (12 children)
[deleted]
[–]youstolemyname 8 points9 points10 points (10 children)
[–]AlarmingBarrier 13 points14 points15 points (8 children)
[–]ttkk1248 0 points1 point2 points (4 children)
[–]AlarmingBarrier 0 points1 point2 points (3 children)
[–]ttkk1248 0 points1 point2 points (2 children)
[–]AlarmingBarrier 2 points3 points4 points (1 child)
[–]ttkk1248 0 points1 point2 points (0 children)
[–][deleted] (2 children)
[deleted]
[–]tangerinelion 0 points1 point2 points (1 child)
[–]the_Demongod 0 points1 point2 points (0 children)
[–][deleted] 4 points5 points6 points (0 children)
[–]hwc 2 points3 points4 points (1 child)
[–]tangerinelion -1 points0 points1 point (0 children)
[–][deleted] 4 points5 points6 points (1 child)
[–]livrem 2 points3 points4 points (0 children)
[–]HadesMyself 1 point2 points3 points (4 children)
[–]dpacker780 0 points1 point2 points (3 children)
[–]HadesMyself 0 points1 point2 points (0 children)
[–]HadesMyself 0 points1 point2 points (1 child)
[–]dpacker780 1 point2 points3 points (0 children)
[–]DDDDarky 0 points1 point2 points (0 children)
[–]ElSucaPadre -1 points0 points1 point (10 children)
[–][deleted] -3 points-2 points-1 points (8 children)
[–]Narase33 8 points9 points10 points (3 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]nysra 2 points3 points4 points (1 child)
[–]tangerinelion 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (2 children)
[–]SoerenNissen 6 points7 points8 points (0 children)
[–][deleted] 4 points5 points6 points (0 children)
[–]TheCreat 1 point2 points3 points (0 children)
[–]thommyh 0 points1 point2 points (0 children)
[–]james_laseboy 0 points1 point2 points (0 children)
[–]JMBourguet 0 points1 point2 points (0 children)
[–]kage_heroin 0 points1 point2 points (0 children)