By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,797 Members | 1,848 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,797 IT Pros & Developers. It's quick & easy.

Deconstructors

P: n/a
Kip
Greetings,

It would seem as though whenever I find a feature that is not in C /
C++, I discover later that it was not implemented for good reason.

I am curious. What was the rationale behind not allowing deconstructors
to take parameters? Or can they and I am mistaken?

--
Kip Warner
Vertigo
http://TheVertigo.com
Jul 23 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...
I am curious. What was the rationale behind not allowing deconstructors
to take parameters? Or can they and I am mistaken?


If they did, how would you use them?
Jul 23 '05 #2

P: n/a
Kip wrote:
It would seem as though whenever I find a feature that is not in C /
C++, I discover later that it was not implemented for good reason.

I am curious. What was the rationale behind not allowing
deconstructors to take parameters? Or can they and I am mistaken?


Destructors are most often called implicitly. If you define one that
takes arguments, what arguments would you want the system to pass?

V
Jul 23 '05 #3

P: n/a
* Andrew Koenig:
"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...
I am curious. What was the rationale behind not allowing deconstructors
to take parameters? Or can they and I am mistaken?


If they did, how would you use them?


One idea that has been floating around is a bool argument that is 'true' if
and only if an exception thrown by the destructor would be caught by some
catch-block or by a hypothetical "..." function try block around 'main' (or
some other specific rule, it may be that this particular one is brain-dead).

Not that I think it's a good idea in general to throw from destructors.

But as I recall one proposed usage of that idea was some kind of scope guard
that threw (?) an exception from its destructor if it hadn't received a
commit() call.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #4

P: n/a
Alf P. Steinbach wrote:

One idea that has been floating around is a bool argument that is 'true' if
and only if an exception thrown by the destructor would be caught by some
catch-block or by a hypothetical "..." function try block around 'main' (or
some other specific rule, it may be that this particular one is brain-dead).


That also requires two-phase exception handling, which is not currently
required. (i.e. the implementation is currently allowed to destroy as it
unwinds, without knowing in advance whether the exception will be
caught) So it's not just adding an argument; it's fundamentally
redesigning exceptions.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #5

P: n/a
Victor Bazarov wrote:
Destructors are most often called implicitly. If you define one
that takes arguments, what arguments would you want the system to
pass?


None, just like with constructors.

I think your argument applies just as well to constructors, which,
after all, are called implicitly with no parameters when an array
is declared. But we don't consider it a problem that one can also
write constructors that take parameters.

However, I suggest that putting destructors with parameters into
the language is still a bad idea. Here is why:

Reason 1

Conceptually, there are usually lots of ways to make something,
but only one way to make it go away.

On the off chance that you can think of several ways to destroy an
object, you can still implement this in C++: store some indication
in the object about how it should be destroyed. The destructor
looks at this and acts accordingly.

Thus, multiple destruction methods can already be done, and it
seems rare enough that it is hardly worth adding new complexity
to the language.

Reason 2

{
Foo x;
x.~Foo(param);
}

x gets destroyed twice: once when I do it explicitly, and once
implicitly when it goes out of scope. This is bad.

Of course, one can call a destructor explicitly even in the current
version of C++, but it is rare, and so when we do it, we often
think carefully about what is happening.

So the real problem with destructors with parameters is that they
make calling a destructor explicitly seem "normal", despite the
fact that it is dangerous.

Jul 23 '05 #6

P: n/a
On Sat, 26 Mar 2005 23:16:04 GMT, "Kip" <Kip@_NOSPAM_TheVertigo.com> wrote:
Greetings,

It would seem as though whenever I find a feature that is not in C /
C++, I discover later that it was not implemented for good reason.

I am curious. What was the rationale behind not allowing deconstructors
to take parameters? Or can they and I am mistaken?


You could fake destructors taking parameters by setting some members just
before the object gets destroyed. For example:

class A {
public:
int dest_param;

A::~A()
{
switch (dest_param)
{
default:
/* ... */
break;
}
}
}

int main ()
{
A inst1;

inst1.dest_param = 123;
/* Destructor gets called at function exit. */
return 0;
}

There isn't a more direct way of doing this - as another poster mentioned,
destructors are called implicitly when an object falls out of scope.

FYI, you can directly pass paramers to the delete operators, but these
might not be as useful for the object that you are destroying as the
example shown above.
Jul 23 '05 #7

P: n/a
* Pete Becker:
Alf P. Steinbach wrote:

One idea that has been floating around is a bool argument that is 'true' if
and only if an exception thrown by the destructor would be caught by some
catch-block or by a hypothetical "..." function try block around 'main' (or
some other specific rule, it may be that this particular one is brain-dead).


That also requires two-phase exception handling


Yes, and it doesn't even tell whether the destructor is called as a result of
stack unwinding or not.

A simpler and more efficient rule could be to have the argument specify
whether the destructor is called directly by exception-initiated stack
unwinding.

That would support the scope guard application (which on reflection the
brain-dead rule doesn't) but not much else.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #8

P: n/a
Kip
Andrew Koenig wrote:
"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...
I am curious. What was the rationale behind not allowing
deconstructors to take parameters? Or can they and I am mistaken?


If they did, how would you use them?


CThing *pThing = new CThing;

delete pThing(5);

--
Kip Warner
Vertigo
http://TheVertigo.com
Jul 23 '05 #9

P: n/a
Kip schrieb:
Andrew Koenig wrote:

"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...

I am curious. What was the rationale behind not allowing
deconstructors to take parameters? Or can they and I am mistaken?


If they did, how would you use them?

CThing *pThing = new CThing;

delete pThing(5);


But what if the thing is on the stack?

void func()
{
CThing thing;
thing.doStuff();
// and now?
thing.~thing(5);
// bad, default dtor still implicitly called at end of scope
}

Cheers,
Malte
Jul 23 '05 #10

P: n/a

"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...
Andrew Koenig wrote:
"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...
> I am curious. What was the rationale behind not allowing
> deconstructors to take parameters? Or can they and I am mistaken?


If they did, how would you use them?


CThing *pThing = new CThing;

delete pThing(5);


I think what was meant was, how whould you use that information? I'm not
sure what, in a destructor, would be useful to know, since the object is
going away anyway and any state changes you make to it will be lost. And
anything that you need to do prior to destruction can be done via a member
function (or by directly accessing public members).

Or, if you need to take some action before destruction, regardless of how
that destruction is going to occur, then you could consider containing your
object inside another object, whose job is to call a member function of that
inner object, prior to allowing everything to be destroyed.

I suspect that the designers simply felt there wasn't any need for such a
construct. Perhaps you have such a need? I sure can't think of one (except
for the idea discussed here regarding exceptions, but that's opening a
bigger can of worms).

-Howard
Jul 23 '05 #11

P: n/a
"Howard" <al*****@hotmail.com> wrote in message
news:Sp********************@bgtnsc05-news.ops.worldnet.att.net...
"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...
Andrew Koenig wrote:
"Kip" <Kip@_NOSPAM_TheVertigo.com> wrote in message
news:xn***************@news.telus.net...

> I am curious. What was the rationale behind not allowing
> deconstructors to take parameters? Or can they and I am mistaken?

If they did, how would you use them?


CThing *pThing = new CThing;

delete pThing(5);


I think what was meant was, how whould you use that information? I'm not
sure what, in a destructor, would be useful to know, since the object is
going away anyway and any state changes you make to it will be lost. And
anything that you need to do prior to destruction can be done via a member
function (or by directly accessing public members).


Moreover, this example doesn't really answer the question, because it covers
only one, fairly uncommon, case. For example:

{
CThing x;
}

At the }, how do you say what argument to give x's destructor?

Or what about this case?

CThing *p = new CThing[100];
delete [] p;

What if you want to give a different destructor argument to each element of
the array?

Or this case?

std::vector<CThing> v;

How do you tell v what arguments to give to destructors when it destroys v's
elements?

This last case is the most interesting, because it is an example of a more
general problem: The part of a program that constructs and destroys objects
of a given type may well be written separately from the definition of that
type itself. So how does one part of the program tell the other part what
destructor arguments to use?
Jul 23 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.