开发者

when to use new in C++?

What's a good policy for when to use "new" to make an instance of a class? I've been hobby programming C++ for a while but I'm still not for sure when is the best time to do this:

MyClass thing(param1, param2);

over this:

MyClass*开发者_开发技巧 thing;
thing = new MyClass(param1, param2);

Any advice?


Design-wise, use automatic (stack) allocation as much as possible. Whenever you need to extend the lifetime of an object beyond a certain scope, then dynamically allocate it.

And even so, never dynamically allocate things raw. Always keep them wrapped into some sort of wrapper that implements Scope-Bound Resource Management (SBRM, first known under the dumb/awkward name Resource-Acquisition Is Initialization or RAII.) That is, dynamic allocations should be kept in automatic objects that will clean up automatically!

A good example of this is std::vector: you cannot leak the memory internal to a vector, because it's destructor is run in every scenario when memory should be free'd, and it will free it for you. auto_ptr is the first and only smart pointer available in the standard library, but it's pretty bad. Better is to use shared_ptr, or many of the other popular smart pointers available in Boost and/or TR1 and/or C++0x.

Performance-wise, objects allocated on the stack can be done so very quickly (the stack size is increased per-function-call, so all the required memory has been allocated up-front by a simple move of a pointer.) Contrarily, dynamic allocation generally requires much more time. It's quite possible to get speedy dynamic allocations with custom allocation schemes, but even the best will still be slower than stack allocation.

Occasionally, you might find you spend too much time copying objects around. In this case, it may be worth it to dynamically allocate it and merely move pointers around. However, please note I said "find". This kind of change is something you find by profiling and measuring, never guessing.

So: Automatic allocation when possible, dynamic allocation when needed.


The first approach creates a local instance on the stack that goes away when the calling function exits. The second creates an instance that stays on the heap until (and if) you explicitly release it again. The choice depends on what kind of control and lifetime you want for your object.


The rule of thumb is: if it works without new, don't use new.


In general: you don't need to use new if you plan to delete the object in the same scope. If the object is quite large, you may want to use new.
You may want to look into the difference between heap and stack memory if you want to know the details.


First, ask yourself the question, does it make sense for the object to be copied when another function wants it?

If it makes sense to copy the object, your best bet is to create everything on the stack or as member variables and then just pass copies around when needed.

If it does not make sense to copy the object, you'll need to use new form so that you can safely pass the pointer to the object. You have to use a pointer (or reference) because as noted it does not make sense to copy the object.

There are two exceptions I'm aware of:

If you know the object isn't going to be used after the current function is finished, you can create the object on the stack so that it is deleted. Just make very sure nobody holds on to a pointer to it afterwards! (I rarely find this is the case, but it happens)

If the object is used internally by another class which itself shouldn't be copied around, you can just put it in as a member variable. Since the object it is in won't be copied, and its only for internal use that will be safe.


 MyClass thing(param1, param2); //memory for thing is allocated on the process stack(static allocation)

 MyClass* thing;
 thing = new MyClass(param1, param2); //memory is allocated dynamically on the heap(free store) for thing

The difference lies here:

 int main()
 { 
   {
    MyClass thing(param1, param2); //thing is local to the scope
   } //destructor called for thing
   //cannot access thing (thing doesn't exist)
 } 

 int main()
 {
   {
     MyClass* thing;
     thing = new MyClass(param1, param2);
   }
  //the object pointed to by thing still exists
   //Memory leak
 }  

For large objects you must allocate memory dynamically(use new) because the process stack has a limited size.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜