Mhmm, I can see 1.2 problems with that approach ...
First, private variables are scoped dynamically, so the private name is only valid in the scope where it was created; when execution leaves that scope the name ceases to exist (although an entity with the same name from an outer scope may become visible and resume duty at that point). This could cause problems if the object lives longer, because it will no longer be accessible by the name it used to have.
First.1, I don't think it is possible to create private
variables (as opposed to private parameters) without triggering a VFP language error. This is a drawback if you subscribe to the 'zero warnings' philosophy.
First.2, private names can clash with attempts to create the same names as globals (publics) further down the road.
I think the cleanest way is to create a global/public name (preferrably salted with SYS(2015) for the sake of global references; the global name does not preclude using local object reference variables when dealing with the object. E.g.
local oFoo, cGlobalName
cGlobalName = "g_Foo" + sys(2015)
oFoo = createobject([CFoo], m.cGlobalName)
assert m.oFoo == evaluate(m.cGlobalName)
oFoo.meow
And in the constructor you would have something like
lparameters cGlobalName
release (m.cGlobalName)
public (m.cGlobalName)
store this to (m.cGlobalName)