Should TDF_AttributeIterator be handled with care?

Today I was surprised to find the following comment within TDF_AttributeIterator.hxx:

// DO NOT USE THIS CLASS WITHOUT AUTHORIZATION!
//
// This class provides a way to iterates on the
// up-to-date (current) valid attributes of a label.
//
// Even a Forgotten attribute may be found if this
// option is set. To use this possibility, look at
// the constructor.
//
// Sorry: nobody needs this iterator but its friends!

I actually use TDF_AttributeIterator now and then, if I want to perform checks or actions on every attribute of a certain label. Why shouldn't I? What is the alternative? Or is the comment some ancient relict that may be removed? Thank you!

Qr Qr's picture

I use it since 2011 and it works nice so far ;)

Benjamin Bihler's picture

Actually I have found something that I dislike. TDF_AttributeIterator returns pointers to the attributes instead of handles. If I would like to store the attribute in a container of attribute handles, I have a problem, since creating a handle out of a pointer means taking control over the object's life time. Since attributes are added to labels by handles, it seems unnatural to me that the TDF_AttributeIterator returns them as pointers.

Andrey BETENEV's picture

TDF_AttributeIterator returns pointers to the attributes instead of handles. If I would like to store the attribute in a container of attribute handles, I have a problem, since creating a handle out of a pointer means taking control over the object's life time.

Note that the last statement is not correct: in OCCT, reference counter is part of the object, thus you can pass C pointer to an object manipulated by handle throughout your code, and then safely create handle using that pointer. That new handle will correctly share the object (unless it has been already deleted).

For instance, this will work:

Geom_Surface* func (const Handle(Geom_Surface)& theSurf1, const Handle(Geom_Surface)& theSurf2, bool useFirst) { return (useFirst ? theSurf1 : theSurf2).get(); }
...
Handle(GeomSurface) aSurf = func (aSurf1, aSurf2, aCondition);

Benjamin Bihler's picture

Thank you very, very much, Andrey, for your comment. I had indeed thought that the reference counter was part of the handle. Actually I had seen in my code that creating handles from pointers sometimes doesn't lead to destruction when the handle runs out of scope, but I hadn't understood the reason for that. I have searched the documentation where this information can be found and to be honest is seems to be described only implicitly in Standard_Handle.hxx.

Qr Qr's picture

That's true. In my code I also have:

    for ( TDF_AttributeIterator attIt(theLabel); attIt.More(); attIt.Next() )
    {
      TDF_Attribute* A = attIt.Value(); // !!!
    }

Do you plan to report an issue in bugtracker?

Benjamin Bihler's picture

Yes, I do. But I won't manage to do that before next week... if you are quicker than me then just go ahead! ;)