2010-10-21 2 views
4

Я пытался определить общий, наследуемый класс TSingleton. Вот что я имел в прогрессе:Может ли общий класс Delphi спуститься с аргумента класса?

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; 

Цель состояла в том, чтобы иметь возможность «вставить» одноплодную шаблон в дереве наследования. так что вместо того, чтобы объявить что-то вроде этого:

TMySingletonComponent = class(TComponent) 

    end; 

И нужно реализовать одноплодный шаблон там, я бы объявить что-то вроде этого:

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

К сожалению, это не будет работать. Я получаю следующее сообщение об ошибке (в D2010):

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

Теперь мне было интересно, что эта работа в Delphi XE? Есть ли какой-нибудь «чистый хак», который я мог бы использовать, чтобы сделать эту работу в D2010? Есть ли какие-то фундаментальные причины, почему это не может работать?

+3

В других кругах, о чем вы спрашиваете, известен как * любопытно повторяющийся шаблон шаблона *, но generics не являются шаблонами. –

ответ

5

По дизайну вы не можете создать общий класс, который является результатом одного из аргументов своего типа.

3

Нет, это не сработает. Вы пытаетесь определить класс в терминах самого себя. Все, что вы ввели в параметры, должно быть полностью определено.

+0

Это не совсем так ... Если я изменю объявление на TSingleton = class (TComponent), то TMyGenericSingletonComponent = class (TSingleton ) работает как шарм. И там параметр еще не будет полностью определен. Если это было то, что вы имели в виду для определения класса в терминах самого себя, это действительно работает. –

2

Что вы хотите получить?

ИМХО, синглтоны являются злыми. Они были введены из-за плохого дизайна ООП C++ (для доступа к потокам ввода-вывода в консольных приложениях, насколько я помню). И они, как правило, как ад для поддержания.

Вы всегда можете жить без них. Это, безусловно, не классический способ программирования Delphi, потому что Delphi не страдает от проблем C++, о которых я упоминал.

Некоторые Java-проекты (ab) используют одноэлементный. Google для этого, и вы узнаете, что я имею в виду.

Использовать свойство общего класса с геттером, инициализируя экземпляр, если соответствующее поле по-прежнему равно нулю или непосредственно возвращает указатель поля к экземпляру, если он уже был создан. У вас будет функция singleton с хорошей производительностью, хорошим кодом, хорошей практикой OOP (нет «глобального» класса) и возможностью запускать класс без какой-либо одноэлементной функции, если эта функция вам больше не понадобится (для тестирования цель, например).

+0

Синглтоны не были введены для C++. Синглтоны существовали до тех пор, пока имеет место структурированное программирование. –