With std::vector, there's no need to delete it (or anything in it) before it goes out of scope. How did they do this? How would I write a class that can do the same?
With std::vector, there's no need to delete it (or anything in it) before it goes out of scope. How did they do this? How would I write a class that can do the same?
Implement the destructor (and the copy constructor and copy assignment operator) wisely.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
You want to implement the destructor to destroy the objects owned by the container (or resource managed by the object, but in such cases it would be smarter to just use a smart pointer to manage the resource... then again it would also be smarter to just use a standard container to manage a collection of objects).How about even some pseudo code? Because I can't seem to find this anywhere. For example, putting "delete this" in the destructor won't actually delete any pointer created of that class' type. So how do I handle that, or is there no way to do so?
A simple/naive implementation of a Vector class might have this destructor:
where data is the member pointer to the dynamic array of objects owned by the Vector.Code:Vector::~Vector() { delete[] data; }
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Your class did not allocate this. It allocated memory pointed to by a pointer member.
For example, if the constructor allocates m_p = new int[10], then the destructor would delete [] m_p.
The copy constructor and assignment operator need to ensure that the ownership of that memory remains clear. For example, if you assign one vector to another, you'll have two vectors with identical contents but each maintaining its own separate buffer.
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
>> With std::vector, there's no need to delete it (or anything in it) before it goes out of scope.
With any class or other type, there is no need to delete it before it goes out of scope. Local objects are always destroyed when the scope ends. A vector is no different.
The only thing that vector does is that it deletes the stuff inside it that it allocated. In fact, from your point of you as a user of vector, you shouldn't think that it deletes anything, that is all internal implementation.
The concept is known as RAII. Since a destructor is called automatically when an object goes out of scope, you can use the destructor to cleanup resources owned by an object. RAII is a very powerful technique in C++ that is not used in Java. Consider reading up on RAII for more information.
Basically you need to understand how the heap and the stack work if you are wondering why you don't delete std::vector objects.
If you allocate something on the heap (i.e. you call new), then you need to delete it when you are done with it. When you allocate something on the stack, you don't need to delete it when you are done. It will be popped off of the stack when it goes out of scope.
Let's look at some examples:
When I do this, I allocate 10 integers on the stack in sequential order. Since they are on the stack, when they go out of scope, they will be popped off the stack, and I don't need to worry about deleting them.Code:int int_array[10];
This code performs a very similar function to the first example, but it allocates the 10 integers on the heap (also in one chunk). Therefore, since I allocated the stuff on the heap, I need to call delete.Code:int *int_array = new int[10];
Now this same principal applies when using objects/classes. Let's say we have the following class:
When myFunc exits, myVector (and everything in it) will be popped off the stack, because everything is allocated on the stack. Now let's take a look at the following class:Code:class vector_int { public: int int_array[10]; }; void myFunc ( void ) { vector_int myVector; }
Here we have a problem. Although myVector is on the stack, I just initialized its member variable int_array to be on the heap. When myFunc exits, myVector will be popped off the stack, but the memory that is on the heap which we allocated will still be there, and there is a memory leak. To avoid this problem, we should really have functions within the class that handle the memory allocation/freeing of pointers within our vector object. Here is a small example (although not 100% complete):Code:class vector_int { public: int *int_array; }; void myFunc ( void ) { vector_int myVector; myVector.int_array = new int[10]; }
Any questions?Code:class vector_int { public: int *int_array; int size; void CopyVectorInt ( const vector_int & copy ) { if ( int_array ) delete [] int_array; int_array = new int [ copy.size ]; size = copy.size; memcpy ( int_array, copy.int_array, sizeof(int) * size ); } void operator = ( const vector_int & copy ) { CopyVectorInt(copy); } vector_int ( ) : int_array(NULL), size(0) { } vector_int ( const vector_int & copy ) { CopyVectorInt(copy); } ~vector_int ( ) { if(int_array) delete [] int_array; } };
Last edited by DavidP; 05-04-2008 at 11:33 AM.
The implementation of CopyVectorInt() would be better placed in the copy constructor (excluding the delete[] int_array). You could provide a swap member function, then implement the copy assignment operator using the copy constructor, destructor, and swap member function. If you do implement CopyVectorInt(), it probably should be private.
The check that int_array is not null in the destructor is unnecessary, and the copy assignment operator typically returns a reference to the current object to allow for operator chaining.
Last edited by laserlight; 05-04-2008 at 11:49 AM.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)