Cancelling a Constructor?

Started by
24 comments, last by neonfaktory 20 years, 9 months ago
quote:Original post by SabreMan
quote:Original post by Sneftel
Another half-witted comment from a half-witted AP. "delete this" is completely legal syntax (though not what is required here).

True. Glaring typo aside, the syntax is legal, but the technique is immoral. What happens if the object is auto? What about references to the object - how do they know the object is `dead''?

It''s a limited technique, but occasionally a useful one. The few times I''ve used it, the following things have been true:

1. The class is a private inner class of another class.
2. The class has a private constructor.

#1 means that you can avoid having references when you don''t want them, since you have full control over when stuff will be used. #2 means that you never have to worry about stack objects.

How appropriate. You fight like a cow.
Advertisement
quote:Original post by Sneftel
It's a limited technique, but occasionally a useful one. The few times I've used it, the following things have been true:

1. The class is a private inner class of another class.
2. The class has a private constructor.

That's nice, but couldn't this be achieved with a static method?
class A{    bool zombie;    A(int x){zombie = (x<0);}    public:    static A* NewA(int x){        A* a = new A(x);         if(a->zombie){delete a; return NULL;} else return a;    }};

An exception could even be thrown and caught internally (thus not requiring the user code to worry about it) instead of having the zombie variable.

Cédric

EDIT: I had made a very stupid error...

I've never done it myself, but this could possibly be done by overloading new.

[edited by - Cedric on July 9, 2003 12:29:15 PM]
You''re right, Cedric. The technique of "delete this" is not especially useful during construction, but rather, at the end of a lifetime. (I was speaking of the usefulness of the technique in general, not in this specific instance.)

How appropriate. You fight like a cow.
for(/*something*/) {  try {    particles.push_back(Particle(x,y));  } catch(CulledException&) {}} 

and
Particle::Particle(float x,float y) {  if(isCulled(x,y))    throw CulledException();  /* ... */}





[edited by - thomas001 on July 9, 2003 12:42:12 PM]
Another issue with aborting constructors with exceptions is that, under certain conditions, an object can be semi-constructed..

if you throw an error in the constructor of a bass class and catch it in the ctor of a subclass - but decide you can deal with it in the subclass without aborting the object then you end up with a partially created object - which can lead to no end of problems..

For example, and I know this is 1) very contrived 2) stupid - but it is still possible and I''ve seen programmers do it..

#include "stdafx.h"#include <string.h>#include <iostream>class baseclass{public:	void setString(const char* const pStr)	{		if(pStr)			m_pString=strdup(pStr);		else 			throw("Invalid String");	}	void printString()	{		std::cout << "String:" << m_pString << std::endl;	}	virtual ~baseclass()	{		if(m_pString)			delete[] m_pString;	}private:	char* m_pString;};class subclass1 : public baseclass{public:	subclass1(const char* const pStr)	{		try{			setString(pStr);		}catch(...)		{			//ignore it - we can deal with - (bad..)		}	}};class errorclass : public subclass1{public:	errorclass()		:subclass1(NULL)	{	}};int main(int argc, char* argv[]){	errorclass e;  //e is never completely created	e.printString(); //bang.	return 0;}


quote:Original post by Sneftel
#1 means that you can avoid having references when you don''t want them, since you have full control over when stuff will be used.

Being a private nested class is not sufficient to tell you whether a reference to an object of that class is dead or alive.
quote:
#2 means that you never have to worry about stack objects.

None of the additional information you mention was present in the code snippet we are commenting on.

This topic is closed to new replies.

Advertisement