Construction always happens from base to derived. And destruction 'should' happen from derived to base. If you are not using virtual function mechanism, it will work as expected, but consider following example,
base *p = new derived();
Here compiler assumes that, p is 'base' type. So unless you make destructor virtual, it will not call derived's destructor. Which may led to memory leak.