Creating C++ objects
I noticed that there are two ways to create C++ objects:
BTree *btree = new BTree;
and
BTree btree;
From what I can tell, the only开发者_JS百科 difference is in how class objects are accessed (. vs. -> operator), and when the first way is used, private integers get initialized to 0.
Which way is better, and what's the difference?
How do you know when to use one or the other?
Two differences:
they create the objects in different parts of the memory (heap vs stack)
the object lifetime is different: In the first case, the code manages the memory allocation explicitly, and it must also manage the deallocation explicitly (using delete/delete[]).
In the second case, the object is automatically deallocated at the end of its enclosing scope (either a method, a nested block within a method, or a class)
Which one you uses depends mostly on the lifetime of the object (if it should outlive the method in which it is created or not).
The first form creates the object on the heap whereas the second creates it on the stack.
The second from will be destroyed when the function is finished running. The first will remain alive until specifically deleted.
The second form is best if you want to only use the object in the current scope. You don't need to worry about getting rid of it because it'll be done for you. Also note that some libraries don't work if there classes are created on the stack.
If the object should outlive the function, the new form is a better option.
Another difference between these two form is the time when storage for those objects are allocated. The form BTree bTree;
names static allocation whose allocation accomplishes at compile time -- i.e. the compiler will arrange memory space for this object in memory when running. While, the allocation for BTree *pbTree = new BTree
, the alleged dynamic allocation -- performs at runtime -- i.e. the momory will be allocated only when the running program reach this point.
In this situation, the difference between static and dynamic allocation is not apparent. Consider the following circumstance where you need to allocate memory space for an integer array, but number of elements can be determined only at runtime, i.e. we can only know the exact memory space consumed by the array after the program begin to execute.
// in this function, we want to return a copy of the parameter array
int *array_cpy( int *arr, int num ){
int *copy = new int[ num ];
int i;
for( i = 0; i < num; i++ ){
copy[ i ] = arr[ i ];
}
return copy;
}
Here the definition int copy[ num ];
is not appropriate, one reason is for what I have stated above, the other is the lifetime of copy
outlive the function. However, given VLA is permitted in recent language specification, the second reason is key to this problem.
In choosing between whether you should stack or heap allocate memory, you need to dig a little into the differences between the two.
Yes, stack memory has the advantage of being deallocated automatically when it goes out of scope, although the same can be achieved with smart pointers and heap allocation. More important are the reasons behind why this happens.
Performance: Stack memory is cleaned up automatically because it involves the simply shift of a stack pointer when the memory goes out of scope. For this reason, allocation and deallocation of stack memory is much faster than heap memory.
Memory Lifetime: Heap allocated memory is available beyond the scope of the allocating function. Stack is not. Following from the reasoning around adjustment of the stack pointer above, once memory is deallocated, it is free and very likely to be overwritten for the next stack allocation.
In short, use stack memory when the allocation is temporary, particularly if you need to allocate repeatedly and performance is important. Use heap memory when the object needs to exist beyond the allocating method.
The high-level distinction is object lifetime. For example, if you were writing a video game, you would allocate the objects corresponding to monsters on the heap, via new
. That way, the monster's underlying object lives exactly as long as the monster does, which is unknowable when you write the program. When the player kills the monster, your code can destroy the monster object using delete
.
A total-score counter, on the other hand, you would use the other form, because you know how long you want the counter to stay around (presumably, as long as the game is running!). By putting that form in the "global scope," outside of any function body, it would be allocated statically, as part of the program binary itself.
Finally, if you were computing the sum of an array, like this:
int mysum(int* arr, int len) {
int sum = 0;
for (int i = 0; i < len; ++i) { sum += arr[i] }
return sum;
}
the sum
variable is allocated on the stack, which is basically what you want: a temporary variable that you don't have to explicitly deallocate, and which is only around when that function is actually running.
Well, they're being stored in quite different regions of memory.
Here's a good read. Heap and Stack
精彩评论