There is only one case where calling the destructor explicitly is valid: when the instance was created with placement new.
Code:
#include <iostream>
using namespace std;
class Test {
int m_Val;
public:
void printVal() { cout << m_Val << endl; }
~Test() { cout << "~Test\n"; }
Test(int val) { m_Val = val; }
};
int main()
{
char buffer[sizeof(Test)];
//put a Test object into the buffer of bytes
Test* p_test = new (buffer) Test(42);
p_test->printVal();
//now call the destructor, which wouldn't be called otherwise
p_test->~Test();
return 0;
}