On 04/07/11 14:55, Dmitry Yemanov wrote: > 30.03.2011 21:45, Vlad Khorsun wrote: > >>> What would do a detach/commit/etc in an object when refcount> 1? >> Call corresponding method of real object. And not touch refcount. >> >>> What would do a detach/commit/etc in an object when refcount = 1? >> Same as above. > Sorry for ignorance, but why refcount is not decremented in these cases? > I mean, what is the point in requiring an extra release() call if the > user has explicitly stated that he no longer needs an object. Note that > we don't require an explicit addRef() call when the object gets created.
To give good answer to this question we should decide, how exact are we going to follow reference counter logic in OLE2. Formal approach says - number of addRef()/release() calls for an object should match. Constructor creates an object with 0 reference counter. When an object is returned from _any_ function, addRef should be called. This addRef is for the process of returning object - imagine that we return not newly created object but already existing. That object may be used in some other place. If it's reference counter is decreased in some other place to become 0 without such addRef() we may return from function pointer to deallocated memory instead good object. Calling the paired release() is responsibility of code which invoked the function which returned an object. There are 2 typical usages: without smart pointers and with them. In the first case typical code looks like: Object* obj = getObject(...); obj->blaBlaBla(); obj->release(); // refCounter becomes 0, object destroyed With smart pointers: Smart<Object> obj = getObject(...); // refCounter == 2 obj->release(); // refCounter == 1 obj->blaBlaBla(); // In ~Smart() refCounter will become 0 and object will be destroyed If we want detach to decrement refCounter (I must say we can do it if we want, we are not OLE2) first sample looks very good for us: IAttachment* att = provider->attachDatabase(...); att->doSomething(); att->detach(); But with smart pointers we must do the following: Smart<IAttachment> at = ... att->release(); // refCounter == 1 att->blaBlaBla(); We want to detach - and here problems come. We can't simply call: att->detach(); because ~Smart() will try to release an already destroyed object, causing AV. From formal POV we must: att->addRef(); att->detach(); which is correct, but ugly. Or we may do the following: Smart<IAttachment> at = ...; // refCounter == 2 att->blaBlaBla(); att->detach(); // refCounter == 1 // In ~Smart() refCounter will become 0 and object will be destroyed This looks good, but somehow breaks smart pointers - if detach is not done, object will leak. On the other hand, this is like ISC API behaves now. Must say that if we decide to use approach with detach() decrementing refCounter(), people may themself choose, what way do they prefer - from fbclient library POV it will make no difference. ------------------------------------------------------------------------------ Xperia(TM) PLAY It's a major breakthrough. An authentic gaming smartphone on the nation's most reliable network. And it wants your games. http://p.sf.net/sfu/verizon-sfdev Firebird-Devel mailing list, web interface at https://lists.sourceforge.net/lists/listinfo/firebird-devel