Use automatic (stack) allocation whenever the function scope - or the scope of a control block such as a for
, while
, if
etc. inside the function - is a good match for the lifetime the object needs. That way, if the object owns/controls any resources, such as dynamically allocated memory, file handles etc. - they will be freed during the destructor call as that scope is left. (Not at some unpredictable later time when a garbage collector winds up).
Only use new
if there's a clear need, such as:
needing the object to live longer than the function scope,
to hand over ownership to some other code
to have a container of pointers to base classes that you can then process polymorphically (i.e. using virtual dispatch to derived-class function implementations), or
an especially large allocation that would eat up much of the stack (your OS/process will have "negotiated" a limit, usually in the 1-8+ megabyte range)
- if this is the only reason you're using dynamic allocation, and you do want the lifetime of the object tied to a scope in your function, you should use a local
std::unique_ptr<>
to manage the dynamic memory, and ensure it is released no matter how you leave the scope: by return
, throw
, break
etc.. (You may also use a std::unique_ptr<>
data member in a class
/struct
to manage any memory the object owns.)
Mathieu Van Nevel comments below about C++11 move semantics - the relevance is that if you have a small management object on the stack that controls a large amount of dynamically allocated (heap) memory, move semantics grant extra assurances and fine-grained control of when the management object hands over its resources to another management object owned by other code (often the caller, but potentially some other container/register of objects). This handover can avoid data on the heap being copied/duplicated even momentarily. Additionally, elision and return-value-optimisation often allow nominally automatic/stack-hosted variables to be constructed directly in some memory they're eventually being assigned/returned-to, rather than copied there later.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…