I read that the destructor should be declared virtual only if there is virtual function in a class. Is this a requirement or is it possible to do otherwise?
You should have virtual destructors if you intend to use your class in a polymorphic setting. If you don't plan to use polymorphism and polymorphic destruction (destruction through a base class) then you don't need a virtual destructor.
Usually, we use classes in a polymorphic setting when there are virtual functions. Having no virtual functions would force to use casts when using the classes. At that point, I would recommend to simply use a variant, which don't require virtual destructors at all.
With all that said, if the only operation you want to expose polymorphically is destruction, it could still be useful in some cases.