seems the destructor of C is being called rightaway within the scope of the line |
Yes. Temporary objects are destroyed at the end of the full-expression that creates them. The "end of the full expression" is intuitively the semicolon at the end of the line.
Classes with virtual functions should
almost always have a virtual destructor.
Prefer member initializer lists over assignment in constructors.
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-initialize
A special member with empty braces is considered to be
user-provided and therefore
nontrivial. Trivial special members allow more opportunity for optimizations. As such, if you do specify special members, avoid empty braces. Instead, explicitly default them or allow them to be implicitly generated.
virtual ~R() = default;
Not all defaulted special members are trivial. This one is not, but it's a good habit regardless.
Make single-argument constructors explicit by default.
explicit C(int m): n{m} { init_th(); }
A non-explicit constructor with one parameter is called a
converting constructor. Only converting constructors are usable in implicit conversions. Mostly, such conversions are undesirable. In this case, for example, it makes no sense for
int to be acceptable where
C is expected, so this constructor should be
explicit.
Don't specify parameters of type
void. It has no purpose and is therefore a waste of time.