简体   繁体   中英

Local variable or a pointer

Given a class in a any random C++ framework, how do you know if you have to create a simple object on stack or a pointer to an object on heap?

Assume a function which accepts argument in the form of a reference(&) variable. The caller can pass a local variable to it or a pointer too(*ptr). The called function may or may not copy dat from the passed object.

This question is a followup of my previous question related to C++ Bada development.

In general, every well-designed C++ library will allow both. In most cases the library doesn't care where the caller allocates memory, since the caller handles its own memory. If the library has additional requirements (eg that it takes over possession of a pointer) then it will carefully document this.

Furthermore, as a general guideline, avoid pointers and freestore memory. C++ is designed with stack objects in mind. If there is no compelling reason to use something different, then don't. new should be used only very sparingly in your code, and delete should never be used – that is, always let your allocated memory be handled in an automatic fashion (smart pointers).

How you create the object depends on what you intend to do with.

If you create an object using new statement, you get a pointer to a manually allocated object. This object will live as long as it isn't deallocated manually, using delete .

If you create a simple object on stack, it remains as long as the current stack is used, that is to say as long as the scope doesn't change.

Common library such as the STL will allow both objects.

If the library has special requirements, it must be documented somewhere, and explained mainly because it want to own the object.

There's no such thing as a "simple object". An object is an object is an object.

What matters is the object lifetime : automatic (scoped), dynamic (manual) or static (permanent).

As much as you can, and unless you have a really, really good reason to do otherwise, use objects with automatic lifetime.

If you think about how one object may depend on another, you'll see that if you only ever use automatic objects, then you won't have a problem with dangling references (or "references to local variable"), because the dependent object will have more deeply nested scope than the referenced object.

You should have a very convincing argument why a particular object must have manual lifetime. These situations happen, of course, but they should be abstracted and factored away. For example, most standard library containers do of course require manual management of their elements, but all that is handled by the container, so that the user can just use an container object of automatic lifetime and all is well. Finally, if you decided that you really must manage an object's lifetime manually, then use a single-responsibility resource managing class like shared_ptr or unique_ptr to pass a handle to that object around -- the handler classes are now automatic again, and once they go out of scope, they release the managed object for you. You get the best of both worlds: the benefits of manual object allocation and scoped responsibilities.

If you follow these ideas methodically, you should find that you will only very rarely create dynamic objects yourself, and if you do, then there's a single line of code that's relevant (this gives you "locality"); for example, auto p = std::make_shared<T>(a,b,c); , or std::unique_ptr<T> p(new T(a,b,c)); . A simple grep for new on all your source code can easily audit whether all your dynamic allocations are handled responsibly.

There are a bunch of things to consider. Lifetime, the need for polymorphism, references and performance are all things to think about when deciding whether or not to use a pointer.

As others have said, stack space has scope lifetime. Once the variable goes out of scope, it's done. The memory allocated through a pointer will persist until delete is called on it, but remember the pointer itself will go out of scope still! So make sure to keep a reference somewhere!

As for polymorphism, using stack space kind of makes that not possible due to the slicing problem. So if you need to use this technique, stick with a pointer.

References should be an obvious one. Do you need to move the same memory around to various places in the program? Do multiple things need to access the EXACT same piece of memory, and not just a copy?

Last, performance. Will using heap memory give you a performance hit? Pointers are slower because of the extra need for allocation time. They also require a bit extra memory to store the pointer itself (insignificant really, but you might as well consider it anyway. Really depends on your application).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM