Yes and no.
Yes, because it is legal in this very short example that you showed.
No, because it can lead to UB, there are some caveats related to using the object during destruction
TL; DR This is always normal if you do not have inheritance.
Now for cases when it is impractical to use the object during destruction.
In the following cases, it is assumed that it is already written
struct V; struct A; struct B; struct D; void foo(A* a = nullptr); struct V { virtual void f(); virtual void g(); }; struct A : virtual V { virtual void f(); }; struct B : virtual V { virtual void g(); ~B() { foo(); } }; struct D : A, B { virtual void f(); virtual void g(); ~D() { foo(this); } }; int main() { D d; }
Virtual function call
After the destruction of x (also as soon as its destructor is called)
If a call to a virtual function uses explicit access to a class member, and the expression of the object refers to the full object x or to one of the subobjects of the base class of the object, but not to x or one of its Saturdays of the base class, the behavior is undefined.
This means that if you use an explicit class member to call a virtual function with a pointer pointing to the entire text of x , but somehow the pointer is not a type of x and its base, the behavior is undefined.
void foo(A* a) { static auto ptr = a; ptr->g();
Using typeid
If the typeid operand refers to the object being built or destroyed, and the static type of the operand is neither a constructor class, nor a destructor, nor its base, the behavior is undefined.
Similarly, if the operand refers to a destructible object, but somehow it is not an object and its basics, the behavior is undefined.
void foo(A* a) { static auto ptr = a; typeid(*ptr);
Using dynamic_cast
If the dynamic_cast operand refers to an object under construction or destruction, and the static operand type is not a pointer to an object or object of its own constructor or destructor class or one of its bases, dynamic_cast leads to undefined behavior.
The same thing.
void foo(A* a) { static auto ptr = a; dynamic_cast<B*>(ptr);
Conclusion
Now, if you think this is a fiasco and donβt understand what is happening, just donβt miss this anywhere in the destructor.
All quotes from http://eel.is/c++draft/class.cdtor