Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Singleton Class in Visual FoxPro 9.0

Singleton Class in Visual FoxPro 9.0

Singleton Class in Visual FoxPro 9.0

I need to create my own Singleton Class using Visual FoxPro 9.0
I tried this:
oRef1 = CreateObject("Singleton")
oRef2 = CreateObject("Singleton")
oRef1.cTest = "Some Text" 

?oRef1.cTest && Some Text
?oRef2.cTest && Prints nothing :(
Release oRef1, oRef2
Clear All

*-- Singleton class
Define Class Singleton As Custom
   cTest = ""
   Procedire Init
      If Type("This.Ref") = "U"
         This.AddProperty("Ref", THIS)
      Return This.Ref
I can't get the same instance. Any help?
Thanks a lot!

RE: Singleton Class in Visual FoxPro 9.0

The only real way to have a VFP singleton is as OLE Public class set to Multi Use.

While Init is the event triggered by CreateObject, its return value is not overriding the reference you get back into oRef1, oRef2, or whatever. Foxpro has no such concept as its init isn't a constructor. "This" is already referring to the new instance of the class and so Init already is the aftermath of the construction of an object.

I find this idea based on THIS_ACCESS: http://www.victorespina.com.ve/wiki/index.php?title=SingletonPattern_(VFP)

Before looking at that it's worth learning how THIS_ACCESS works as a special access method for an object itself. Unlike the property_access methods you can generate when defining a new member (property) of a class, this is for the object itself and gets invoked from access to any member with the member name as parameter. You get standard behavior when returning THIS from THIS_Access (notice you don't return THIS.&cMember) and that's used here to let access to any instance be redirected to a central instance. Also note, this isn't only working for property members, also for methods and events. Redirecting to another object the call to methods also is redirected - using the same parameterization as the original call to THIS was using.

The first instantiation already creates a second object stored as _SCREEN child object and any access to members (except a few methods and properties) is then redirected to this _SCREEN child object. I'd perhaps change this so the first instantiation puts itself (THIS) to a _SCREEN property instead of creating another instance of its class.

The downside of that is, that the THIS_ACCESS method doesn't work with OLE public classes. But then we have Multi Use instantiation for OLE classes.

In a way, this is okay, as OLE class usage always is slower than native class usage. But if you even look for a singleton spanning multiple VFP processes (eg preventing multiple starts of an application) the Multi Use OLE mechanism works that way and there are solutions using some kind of mutex: FAQ184-1767: Only one instance of an application

PS: You can also find about other instances with AINSTANCE(), but this function only sees instances in variables and (what's not documented) only in variables in scope. I tried putting AINSTANCE into the init so the class init puts a reference to the first instance into a property, but that won't see previous instances stored in local variables, for example, so AINSTANCE() is of limited use.

Bye, Olaf.

Olaf Doschke Software Engineering

RE: Singleton Class in Visual FoxPro 9.0

And just a few remarks.

What you tried with "This.Ref" would only work, if the singleton would be a static class, but VFP lacks that concept overall, we just have public (by default), private and protected classes or members and even these concepts are flawed in some cases. This.Ref already is the Ref property of a separate new instance in your code, so that won't work. You can't set the Ref property to be a static member.

I just had another idea, which kind of works, but not with the object itself:


oRef1 = CreateObject('singletonproperty')
? oRef1.cFirstInstanceSys2015 
? oRef1.nFirstInstanciationTime 

oRef2 = CreateObject('singletonproperty')
? oRef2.cFirstInstanceSys2015 
? oRef2.nFirstInstanciationTime 

* only releasing all instances and clearing the class definition from memory you get a new evalutaion of cFirstInstanceSys2015 and nFirstInstanciationTime.
Store null to oRef1, oRef2
Clear Class singletonproperty

oRef3 = CreateObject('singletonproperty')
? oRef3.cFirstInstanceSys2015 
? oRef3.nFirstInstanciationTime 

Define Class singletonproperty as Custom 
   cFirstInstanceSys2015 = Sys(2015)
   nFirstInstanciationTime = Seconds()

If you could define a property oSingleton = THIS, that only would be evaluated in the first instantiation and every other instance of the class would have a reference to the first instance, but VFP doesn't allow referencing THIS in such initializing values of class properties. If this would work, you'd need a THIS_ACCESS method returning THIS.oSingleton. Well, aside of the fact ideally you wouldn't even have further instances. But that's only possible with Multi Use instantiation of OLE classes, that's why I initially said it's the only real way.

The implementation of Victor Espina also doesn't prevent multiple instances, all instances just redirect their own usage to an instance created as _SCREEN property. That's why this only works for classes you can put into a property and the class definition better is a flat class, no object properties like controls on a form. They do work, that's not the reason I say better a flat clas, access to any of the child object goes through the topmost object THIS_ACCESS and childobjects don't need their own THIS_ACCESS method at all, but the more complex a class is with all its child objects, the more memory you still allocate, the more init code and anything done in it like data binding queries still runs. Only all usage of the additional instances after their init is redirected to the initial instance.

Bye, Olaf.

Olaf Doschke Software Engineering

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close