views:

98

answers:

3

I've been trying to define a generic, inheritable TSingleton class. Here's what I had in progress:

  TSingleton<RealClass, InheritsFrom : class> = class(InheritsFrom)
  strict private
    class var FInstance : RealClass;
  protected
    procedure InstanceInitialization;virtual;
  public
    destructor Destroy; override;
    class procedure Create; reintroduce;
    class function Instance : RealClass;
    class procedure InstanceFree;
  end;

The goal was to be able to "insert" the singleton pattern in an inheritance tree. so instead of declaring something like this :

  TMySingletonComponent = class(TComponent)

  end;

And need to implement the singleton pattern there, I would declare something like this :

  TMyGenericSingletonComponent = class(TSingleton<TMyGenericSingletonComponent,TComponent>)
  end;

Sadly, this won't work. I'm getting the following error(In D2010):

  TSingleton<RealClass, InheritsFrom : class> = class(InheritsFrom) ///E2021 Class type required

Now I was wondering, would this work in Delphi XE? Is there some "clean hack" I could use to make this work in D2010? Is there some fundamental reasons why this can't work?

+3  A: 

No, that won't work. You're trying to define a class in terms of itself. Whatever you put inside the parameters has to be fully defined already.

Mason Wheeler
That is not completely true... If I change the declaration to TSingleton<RealClass : class> = class(TComponent), then TMyGenericSingletonComponent = class(TSingleton<TMyGenericSingletonComponent>) works like a charm. And there, the parameter wouldn't be fully defined yet. If that was what you meant about defining a class in terms of itself, well, it does work.
Ken Bourassa
+5  A: 

By design, you can't create a generic class which derives from one of its type arguments.

Barry Kelly
+1  A: 

What do you want to obtain?

IMHO, singletons are evil. They were introduced because of bad OOP design of C++ (for access to input/output streams in console applications, as far as I remember). And they tend to be like hell to maintain.

You can always live without them. It's definitively not a "Delphi classical" way of programing, because Delphi doesn't suffer the C++ problems I mentioned.

Some Java project (ab)uses of singleton. Google for it, and you'll find out what I mean.

Use a property of a common class with a getter, initializing an instance if the corresponding field is still nil, or directly returning the field pointer to the instance if it was already created. You'll have the singleton feature, with good performance, nice code, good OOP practice (no "global" class), and the ability to run the class without any singleton feature, if you don't need this feature later (for testing purpose, for instance).

A. Bouchez
Singletons were not introduced for C++. Singletons have existed for as long as structured programming has.
Rob Kennedy