A destructor is a method in Object Oriented Programming that allows the programmer to clean up their mess before they abandon an object.
Yeah, but why would anyone want to do that?
During the life of an object, it may allocate memory, create pointers, references, linked lists, or other constructs which eat memory. Sometimes when you're done with an object and you don't have an adequate destructor, these resources will still be reserved by your program, and therefore not available to other processes. Even your program can't re-grab them. Since your program can no longer use them, and they're off-limits to other programs, these resources are in limbo and are rendered useless. This is called a memory leak.
Memory leaks are generally considered bad juju in programming circles.
In Java there are no explicit destructors, because of the garbage collector, which eliminates the need for the programmer to manually clean up the mess. When the commode is flushed on your object, as it were, the garbage collector wipes your bum for you, blows your nose and offers you a mint. Any resources your program has snarfed up are released back to the heap. All this is done without the knowledge or consent of the programmer.
In Visual Basic there is a combination of manual and automatic destruction. You can't deallocate anything (because you were never allowed to allocate it in the first place), but you can handle any last minute details before your object bites the dust. And if your object was holding any resources, they are dropped before the object is destroyed. This is done through your class's Terminate Function.
In C++, you had better keep track of anything that may need to be released, because there is no garbage collector whatsoever. You're on your own. The destructor is indicated by a bitwise complement operator (~) followed by the constructor's name (get it?). So if your constructor was called "MyObject()", the destructor would be called "~MyObject()".
Addendum Oct. 30, 2002: ariels has just reminded me that destructors are not only for deallocating memory. He gives me the for instance: "the fstream destructor closes the file -- it releases a file descriptor (and, if based on libc, also a file pointer)."
Basically the destructor is for any cleanup operation. I, personally, use it most often for deallocating memory, releasing pointers, and when using sockets, calling the WSACleanup routine.