TDPL: Manual invocation of destructor

Michel Fortin michel.fortin at michelf.com
Tue Aug 10 07:33:24 PDT 2010


On 2010-08-10 09:21:30 -0400, Andrej Mitrovic 
<andrej.mitrovich at gmail.com> said:

> I see. I agree clear() is definitely safer in these situations. But if the
> constructor gets called again automatically after clear(), that would mean
> the other references could still use the object since it's in a valid state
> again, right?

The object you cleared might be in a valid state itself, but it might 
have broken a larger system relying on the state of that object. 
Normally you'd encapsulate this state with 'private' or other 
protection attributes to prevent accidental changes, but clear() 
bypasses all that.

For instance, let's say a class and a struct are used to keep track of 
the current number of 'users' for of each specific instance:

	module myobject;
	
	class MyObject {
	private: // only the struct User (in the same module) can access this
		int userCount;
		void addUser() { ++userCount; }
		void removeUser() { --userCount; }
	}

	struct User {
		MyObject object;
		this(MyObject o) { o.addUser(); object = o; }
		~this() { o.removeUser(); }
	}


	module main;
	import myobject;

	void main() {
		MyObject o = new MyObject;
		{
			User u1 = User(o); // o.userCount == 1
			User u2 = User(o); // o.userCount == 2
			clear(o);          // o.userCount == 0
		}
		// after u2.~this(): o.userCount == -1 !!
		// after u1.~this(): o.userCount == -2 !!
	}

Here you see clear() is playing havoc with userCount, and you can't 
rely on protection attributes to guard against it.

The same applies if you have immutable members in your class: someone 
might be relying on it, have a reference to it, but clear() destroys 
this type system guaranty.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list