7 ms·
Why should I use a pointer rather than the object itself?
- GuiA 13y agoRelated Stack Overflow question: "C++: Why should `new` be used as little as possible?" https://stackoverflow.com/questions/6500313/c-why-should-new-be-used-as-little-as-possible https://stackoverflow.com/questions/6500313/c-why-should-new...
- gd1 13y agoThere are some very good answers to that question. Related to that question, I still fail to see any advantage to using shared_ptr, weak_ptr, unique_ptr, auto_ptr, etc. If you are doing C++ right, nearly everything should be allocated on the stack, and the things that aren't should be encapsulated in a class, RAII style. If you can't design your program so that the ownership and lifetime of your objects are clear, then you're using the wrong language, and shared_ptr won't save you.
- dllthomas 13y agoThe various pointer types are about keeping the ownership and lifetime of your objects clear.
- gd1 13y agoThey have no real reason to exist. At best, they are syntactic sugar (auto_ptr), at worst they actually encourage poor design (shared_ptr). They are basically a crutch for programmers who grew up with managed languages and are afraid of raw pointers.
- penguindev 13y agoOh please. They help with exception safety, and sometimes you do transfer ownership or have unknown lifetimes.
- gd1 13y agoHow did we ever survive without them, before boost showed up? I seem to remember doing just fine. They are a symbol of the useless bloating of C++, a language trying to be all things to all people. A half-assed halfway house between managed and unmanaged. You're either a competent C++ coder, in which case you shouldn't need them, or you're new to the language, in which case they are obfuscating the details that you need to learn. > transfer ownership Then transfer ownership. The object that owns them encapsulates a container. When it is destroyed, it iterates the container and destroys the objects that it owns. So to transfer, take it out of that container and pass it to the new owner. It isn't rocket science. >unknown lifetimes Then you have a lazy, poor design. And that's the point really, managing your memory properly is an intellectual rigour - it forces you to improve your design, to be acutely aware of these issues. Not just spawn shared_ptrs and hope for the best. We have nice forgiving languages where you can be lazy. Coding in C# is like taking a holiday. C++ is meant to be hard.
- Morgawr 13y ago>C++ is meant to be hard. I thought C++ was meant to be a lot of things but I don't think it being "hard" was one of the key points of its inception. Just because you're using a "hard" language, it doesn't make you a better programmer. If the language can be made easier, more productive to write, with less problems and bugs due to memory leaks and inaccuracies, while not impacting performance, why wouldn't you want to do that?
- gd1 13y agoThat's like asking a marathon runner why he doesn't just hop in a car. I use many languages. I use C# to knock out a GUI. VBA for a bit of spreadsheet work. Q/KDB+ for database/functional work. R for stats. All of these are far more productive than C++. If you want fancy abstractions, other languages have them by the bucketload. I don't use C++ to be productive, and I don't expect to be. I use it to get close to the metal and have full control. Everything you code will take 4-5 times longer to write. And longer to compile. You will be careful because you have to be careful, and that's a good thing because with that care comes quality.
- dllthomas 13y agoThat's just false. The automated cleanup could be done manually, but the type safety is invaluable. Change how you want to handle ownership of a particular object as part of a refactoring. Now, find everywhere that assumes the previous model - if you use bare pointers, it's a pain in the ass. USE TYPES TO HELP YOU WRITE CORRECT CODE. I do a lot of this in my C code.
- Suncho 13y agoThe point of the smart pointers is that they are RAII classes. If you have an object that manages more than a single resource, you open yourself up to all kinds of exception safety and thread safety issues. For example, let's say you have a class that news up an object in its constructor. Presumably, the corresponding delete lives in the destructor. But if that constructor throws an exception, the destructor will never be called. If it throws the exception after the "new," then you have a memory leak. So basically, you need a class whose only job is to manage a single pointer. You could certainly roll your own smart pointer, but it would have to work pretty much exactly like one of the ones in the standard library.
- srean 13y agoThe word RAII by itself is too non-specific. People typically mean: use (i) a scoped/auto pointer or (ii) a shared pointer (thats C++ speak for reference counted pointers). These are good thumb rules to rely on, but in itself they are very inadequate. First, auto or scoped pointer gets you a stack discipline. If your objects weren't very big, you might as well create them on the stack itself. More efficient and suitable for multithreading. If the lifetime does not follow the lexical stack then you are out of luck with this style of RAII. Next, reference counted pointers: Cycles are clearly a problem. The traditional mantra is: use weak pointers to break cycles, but then you are back to error prone manual management (of cycles). If I am to be trusted with using weak pointers correctly, I wouldn't be too bad with manual memory management either. Pure functional languages with eager semantics do not allow cycles, so are ref counts a good idea in such cases ? Although, many do not think about it that way, reference counted system is a _garbage_collector_. Just a particularly simple one. Just because one understands how it works, does not disqualify it from being a garbage collection system. It is just not a very efficient garbage collector for cases where running time is sensitive to cache locality, which is true fairly often. I am quite excited about Rust's regions. I dont think programming with regions is easy and you would want to have a garbage collector anyway. I hope this style of programming sees more mainstream visibility. Something should come out of all the MLton work on this. EDIT Indeed meant MLKit but it draws enough from MLton that I thought HNers would be able to relate. There is also D's scoped guards, but I am not yet familiar with what they do.
- gd1 13y ago>reference counted system is a _garbage_collector_ Exactly. An awful one.
- penguindev 13y agoSo why did Apple switch to ARC?
- masklinn 13y agoObj-C has been a (non-automatic) refcounted language since its inception, save for a very short period of more advanced GC on OSX (the GC never made it to iOS). Also, ARC is not a refcounting GC, the ARC calls are injected statically in the binary as if they'd been inserted manually in the source.
- nsmnsf 13y agoCan someone explain RAII to me? In the way that it's commonly used, it seems like it really means "stack variables that go out of scope are deallocated", which seems kind of, well, duh? I don't really understand why it's treated like a big deal. (I mostly write C + Obj-C)
- julian37 13y agoStack variables that go out of scope are deallocated, that's one of the points of RAII (an advantage over dynamic allocation, especially because scope is also terminated by exceptions.) But crucially, their destructor is called (and any destructors of their member variables, etc.) The destructor might perform cleanup work beyond freeing up memory. For example, std::istream will close the file handle when it goes out of scope, and boost::lock_guard will release the lock. RAII isn't rocket science, but there are some advantages over plain C where all cleanup has to be explicit and it's fairly easy to get resource deallocation wrong if you don't know what you're doing. And as the Wikipedia article says, RAII is vital in writing exception-safe code in C++ if you don't want to litter try/catch blocks all over your code. http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial...
- dllthomas 13y agoRAII is "Resource Acquisition Is Initialization", and it means "tie the lifetime of a resource to the lifetime of an object" because we have ways of making sure objects are released when they are no longer wanted (of which stack allocation is the easiest, when it's applicable).
- DerKommissar 13y agomutex.lock(); doStuff(); /*throws an exception, mutex is never unlocked*/ mutex.unlock(); ScopedLock lock(mutex); doStuff(); /*mutex unlocked by destructor in all cases*/ It guarantees that resources are freed no matter how the scope exits.
- coherentpony 13y agohttps://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initia...
- joe_the_user 13y agoOne interesting thing is that the QT framework prefers the use of pointers over reference variables. There's actually some reasonable logic here. Pointer syntax clearly shows you are acting on something in a different way than you act on an "ordinary" object. Reference object syntax is the same as ordinary object syntax but you are making changes that will go beyond the local scope and that is thus less obvious. With this approach, you can still allocate objects on the stack - you then take their address and pass that to a subroutine.
- acchow 13y agoPresumably, this pointer vs. reference debate is only relevant in C and no longer has a place in C++ with the use of unique_ptr, shared_ptr, std::move, etc?
- ori_b 13y agoC has no references -- 'type& param' -- so there is no debate. This is a topic exclusive to C++, and isn't affected by smart pointers, which overload all the pointer operators in order to act like regular pointers, only with some sort of lifetime management.
- EpicEng 13y agoConsidering that C has no notion of references, no, I cannot agree...
- joe_the_user 13y agoIn the Qt idiom, these smart pointers are irrelevant (as mentioned in the other poster). Here, when you are passing a pointer, it's going to be a pointer to an object on the stack which is always going to be good - the pointer argument shows you that you are dealing with something outside the functions local scope, the variable allows you pass information back, etc. Qt also has used its own smart pointers for a while but these generally are declared within some container class, so the idiom basically allows you to do allocation entirely within containers and so never use the new operator directly. Now, there may be situations where you have a complex chain of multiple connections that don't fit to an existing container. The sloppy way then is to use new and the good way to write a custom container. The idiom can also when dealing external libraries that allocate memory directly or somehow demand you use the new operator.
- stormbrew 13y ago> note: in java, everything(except basic types) is a pointer. so you rather should ask the opposite: why do I need simple objects? I think this is by far the most important piece of advice in that thread. It gets right to the heart of one of the most basic areas of confusion that programmers coming from garbage collected environments to ones with manual memory management have. They need to understand that they have NOT been working in an environment without pointers, as they are often told to believe, but one in which nearly everything is a pointer. Understanding this is fundamental to understanding these differences and a 10,000 word essay about C++ allocation policies will not make it any clearer without dealing with that first.
- malisper 13y agoBut the fact that they are programming in an environment where everything is a pointer is hidden to the them. In C++ one needs to explicitly use pointers whereas in Java all of the pointers are handled behind the scenes.
- abengoam 13y agoNot really. In Java it's a leaky abstraction - it's true that the JVM does a lot of micromanagement for you, but if you are careless you start getting exceptions (best case scenario) or start to get mysterious changes in your data (worst case scenario). I agree with grandparent that understanding what a pointer is and that almost everything in a Java program is a pointer it's critical for a Java programmer.
- banachtarski 13y agoI'm amazed at how many new programmers enter the workforce without a basic understanding of the stack and the heap.
- IsTom 13y agoI've met an 'architect' who didn't know either. Apparently Java world is governed by a different set of rules.
- 13y ago
- Suncho 13y agoI find it interesting that nobody mentions iterators anywhere in this discussion. One of the main uses of pointers is to iterate through data. Pointers are the most basic form of iterators in C++. STL iterators are based on, and often implemented in terms of, pointers.
- EGreg 13y agoOne is allocating on the stack and one on the heap. Allocating on the heap means you have to delete it yourself in C++. It's pretty staightforward, no?
- orionblastar 13y agoI audited a few MOOC classes. They don't even bother to teach pointers, the stack, or heap. It just confuses the students they claim. Also teach students to store the value of PI into an Integer. Use DRJava and Java 6 and some bloated JAR library that makes Windows crash. When I studied computer science in 1986, the very first things we learned where how memory and binary worked, plus what a pointer was and why it should be used and how to manage memory so it would not crash and lock up. We learned how to debug as well. Most comp sci graduates that I talk to know almost nothing of how a pointer works, or the stack or heap, and binary might as well be Tagalog to them. I think that over the years as the demand for IT workers increased, they relaxed the standards they used in teaching computer science and programming. Any good MOOC should teach: Pointers The Stack The Heap Binary Hexadecimal How to debug code Assembly Language instructions the code gets converted into and how to debug that
- Jonathan_Swift 13y agoIt's not always obvious. Quite commonly one is used when the other would be better, even by otherwise good coders. To beat the subject completely to death: Pointers, References and Values Passing Parameters, Returning Results, and Storing Member Variables with Musings on Good C++ Style http://www.warplife.com/tips/code/c++/memory-management/parameters/ http://www.warplife.com/tips/code/c++/memory-management/para...