Topic: Syntax for explicit call of destructor
Author: Niall Smart <njs3@doc.ic.ac.uk>
Date: 1998/05/31 Raw View
Hi,
I'm hoping someone with a copy of the FDIS can clarify this; unfortunately
I only have a copy of the December 96 draft.
Section 12.4 [class.dtor] point 12 describes the syntax used to explicitly
call a destructor of a class:
12In an explicit destructor call, the destructor name appears as a ~
followed by a type-name that names the destructor's class type. The
invocation of a destructor is subject to the usual rules for member
functions (_class.mfct_), that is, if the object is not of the
destructor's class type and not of class derived from the destructor's
class type, the program has undefined behavior (except that invoking
delete on a null pointer has no effect). [Example:
struct B {
virtual ~B() { }
};
struct D : B {
~D() { }
};
D D_object;
typedef B B_alias;
B* B_ptr = &D_object;
D_object.B::~B(); // calls B's destructor
B_ptr->~B(); // calls D's destructor
B_ptr->~B_alias(); // calls D's destructor
B_ptr->B_alias::~B(); // calls B's destructor
B_ptr->B_alias::~B_alias(); // error, no B_alias in class B
--end example]
This means that if I were writing a function which takes a pointer to
a T and destructs it then I should write it like this:
void destruct(T* t)
{
t->~T();
}
and not:
void destruct(T* t)
{
t->T::~T();
}
because this latter syntax is incorrect if T is a typedef for a class. What
about scalar types though? Section 5.2.4 [expr.pseudo] has this to say:
5.2.4 Pseudo destructor call [expr.pseudo]
1 The use of a pseudo-destructor-name after a dot . or arrow -> opera-
tor represents the destructor for the non-class type named by type-
name. The result shall only be used as the operand for the function
call operator (), and the result of such a call has type void. The
only effect is the evaluation of the postfix-expression before the dot
or arrow.
2 The left hand side of the dot operator shall be of scalar type. The
left hand side of the arrow operator shall be of pointer to scalar
type. This scalar type is the object type. The type designated by
the pseudo-destructor-name shall be the same as the object type. Fur-
thermore, the two type-names in a pseudo-destructor-name of the form
::opt nested-name-specifieropt type-name :: ~ type-name
shall designate the same scalar type.
If I read this correctly then given:
typedef int I;
typedef int J;
typedef int K;
I* q;
all the following variants invoke the pseudo destructor for q:
q->int::~int();
q->I::~J();
q->int::~K();
but these are syntax errors:
q->~int();
q->~I();
Therefore when writing my destruct function above, I have to know if T is a typedef
name for a class or scalar type to write it correctly:
for a scalar typedef: t->T::~T();
for a class typedef, or class name: t->~T();
Is this correct?
Niall
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]