>Here I am not certain I interpret you correctly - do you mean [GUI] control(s) tree or do you echo the the MS vfp help dichomoty of "containers" vs. "controls" (grouping cursoradapter with controls, but optgroups not...).?
AddObject() is what's primarily used for object composition in the form designer and I think that's its main reason for existing as it knows what to do with containers etc. as well as with plain objects. Other than adding objects to the control tree I would never use AddObject() - I would always use ADDPROPERTY for mere consistency with other code - ADDPROPERTY all the places.
>IAC - in vfp object hierarchies I tend to think/worry only about 2 odd corners:
>member classes and phantom objects sometimes cropping up on .RemoveObject if said object was added via class inheritance. Not certain if .prg/.vcx/scx plays a role - fools luck and a simple KISS rule kept me out of trouble. Rule simply is: if any object can be exchanged/deleted, add the object dynamically via running code, not at design/pre-compile time.
>So I am happy creating biz hierarchies on custom - while heavier than line, unless oodles are needed, always basing biz objects on line and .addproperty borders on premature optimization in my book, unless you already have all the necessary routines finished from previous project ;-)
I think at one time the base class might have made a difference, but with current hardware performance and memory availability I don't think you're even going to be able to measure the difference in performance for class differences except in extreme cases.
The performance hits come from other things like adding things to collections/arrays and looking up things in a control tree, or in collections. When I wrote the Web Control Framework for Web Connection which basically managed its own control key for all dynamic HTML elements, the overhead of walking the tree was huge. I went as far as playing around with different base classes to see if that would make a different, but it didn't in a significant way.
In general my rule is basically this: Use EMPTY if it works and especially for data entities - otherwise use Custom unless you have a specific need for a given base class to inherit functionality from.