4 ms·
Excuse this ignorance from C# land, but how does one get by in C++ without ever writing "new"?
by Gene_Parmesan 7y ago
Excuse this ignorance from C# land, but how does one get by in C++ without ever writing "new"?
- zabzonk 7y agoUse the Standard Library, which safely encapsulates new and delete.
- Gene_Parmesan 7y agoSmart pointers and so on? As I said in another sibling reply, I have experience in almost everything from C# down to C, functional, etc., with the (almost) sole exception of C++, so I'm always curious in understanding that language's idioms. The idea of needing to employ the standard library to avoid using a core feature of the language seems... interesting? I guess.
- detaro 7y agoYou couldn't implement the standard library or libraries providing tools like the standard library without having "new" etc available in the language. And of course C++ hasn't had all of this from the start, some use cases still like or need to avoid using too much of the standard library, ...
- ncmncm 7y agoMost such cases are delusory. That said, anyone who needs more than a couple of std::shared_ptr in a program is probably Doing It Wrong. I rarely find a use for them; prevalence of std::shared_ptr is often called Java Disease. Similarly, for std::unique_ptr in public interfaces. Finally: implementers of the Standard Library are not confined to using only Standard facilities, so in fact they do not actually need op new. In practice, they use it, but always correctly so you don't typically need it at all.
- zabzonk 7y agoMostly using collection classes such as std::string, std::vector, std::map and so on, but also using smart pointers such as std::unique_ptr for lower-level stuff. And of course, the Standard Library is built on those "core features" - it just makes them easier and safer to use.
- kitd 7y ago'new' allocates an object on the heap, where it is prone to being leaked. Direct allocation on the stack (and maybe moving to the caller function if needed) keeps everything local and ensures destructors are always called when the stack unwinds.
- Gene_Parmesan 7y agoRight, I guess the thought of never having any heap-based allocation just seems... curious to me, I guess. I have lots of C# (and Java, and Python, and...) experience, and a fair amount of C experience, but I've managed to skip past C++, so many of the idioms I see in modern C++ are fascinating for me.
- hellofunk 7y agoThis isn't really the right concept. Lots of objects must be on the heap, as the stack cannot contain them. The question isn't to avoid putting objects on the heap, it's to avoid the use of "new" to put them on the heap. Modern C++ encourages avoiding manually using "new" and relying on smart pointers for that, as they will automatically call "delete" and avoid a large class of memory leaks from heap usage. Note that member objects are often on the heap without using any smart pointers or use of "new" simply because they inherit the memory area from their enclosing object, and I've see many inexperienced C++ devs manually allocate memory for these objects unnecessarily.
- kitd 7y agoThanks. Your answer captures the nuances much better than mine. I was concentrating simplistically on the difference between heap and stack allocation, but that misses a lot of the common usage & idioms.
- detaro 7y agoUse smart pointers, put things in containers or inside other objects, ...
- gumby 7y agoOne way is to stack allocate it `foo temp_foo { 1, “bar” };`. Another is to ‘emplace’ straight into a container. When the container is deleted so are the objects. A third is to use `std::make_shared<foo>(1, “bar”)` or std::make_unique.
- MauranKilom 7y agoIf you `new` something, you must `delete` it exactly once. The constructor and destructor of a class are ideal for this because they are paired like this. But if your class does (memory) resource management like this, it should only do resource management, else it would violate the single responsibility principle. This naturally leads to classes that are solely about resource management, where you only express the intended ownership (e.g. unique or shared) and this dedicated class ensures every `new` is matched with a `delete`. Those of course exist in the standard library (since C++11): `std::unique_ptr` and `std::shared_ptr`. Similar story for arrays: Use `std::vector` if you need a dynamically sized array. It will do all the bookkeeping and memory management you'd have to do with `new T[N]` but it does it right. It's not about avoiding heap allocation, despite the association that several people are bringing up here. It's about "express and abstract the resource management strategy instead of reimplementing it everywhere and obscuring it to readers".