Akito Nozaki
anpluto@usa.net
2004.03.10

Please read the article Justin Karneges has written. I am adding on another solution/method/suggestion to his article ^^

http://affinix.com/~justin/signalsafety.html

My suggestion is to extend the deleteLater() function.

class example : public QObject
{
	Q_OBJECT
	...
	slots:
		void deleteSafe();
		
	private:
		bool delsafe;
	...
}

void example::deleteSafe()
{
	if(delsafe)
		delete this;
	else
		QTimer::Singleshot(0, this, deleteSafe());
}

Unlike deleteLater, deleteSafe will keep on waiting until the class resets the flag to true.

Here is an example:

class example : public QObject
{
	Q_OBJECT
	...
signals
	void error();

slots:
	void deleteSafe();

private:
	int x;
	Foo *f;
	bool delsafe;
}

example::~example()
{
	if(f)
	{
		f->deleteSafe();
		f = 0;
	}
}

void example::deleteSafe()
{
	if(delsafe)
		delete this;
	else
		QTimer::Singleshot(0, this, deleteSafe());
}

void example::process()
{
	...

	if(problem) // first case
	{
		delsafe = false;
		emit error();
		delsafe = true;
		
		x = 12;
		return;
	}
	else // second case
	{
		emit error();
		return;
	}
}

void myclass::slot_error()
{
	if(temp)
	{
		temp->deleteSafe();
		temp = 0;
	}
	
	QMessageBox::information(0, tr("Error!!"), tr("ERROR!!!"));
}

Cool isn't it ^^ Since this way is so generic you can add a define such as q_sdelete and always work.

In first case:
Since we set safedelete to false, when slot_error uses the safeDelete the class will only schedule the delete. When the class is ready/safe for delete. The class will set safedelete to true, and the class is deleted at next event loop.

This is like deleteLater but will wait until it returns from the function and finishes the process() function.

In second case:
The safedelete isn't set. So the delete occurs immediately.


Now, if Trolltech implements this into QObject this is what the code might look like

#define qt_sfdelete(a) { if(a) {a->safeDelete(); a=0;} }	
class example : public QObject
{
	Q_OBJECT
	...
signals
	void error()

private:
	int x;
	Foo *f;
}

example::~example()
{
	qt_sfdelete(f);
}

example::process()
{
	...
	if(problem)
	{
		setSafeToDelete(false);
		emit error();
		
		setSafeToDelete(true);

		x = 12;
	}
	else
		emit error();
}

void myclass::slot_error()
{
	qt_sfdelete(temp);

	QMessageBox::information(0, tr("Error!!"), tr("ERROR!!!"));
}

Clean and simple (^^)


Of course this method has its weakness. The problem with this is that the user can not call "delete" and must call safeDelete. With Justin's method, the user does not have to worry about this.


Yes, many ways to deal with this problem but if Trolltech is going to help us out. I think they should add this feature into QObject. Since its very similar to deleteLater(), it should be easily adapted by others and should completely eliminate the need of deleteLater().

Thanks To: