Bottom line: How can we hide the constructor of a class? As far as I can see you cannot decrease the visibility of a method compared to it's inherited class. Why shouldn't we be allowed to? C++, C# does!
I found this by trying to implement a True Singleton in Free Pascal / Delphi. For those that don't know, a Singleton is a Design Pattern that allows only one instance of a class. It seems it is impossible to do in Free Pascal / Delphi. :-( See attached code for a demonstration of the problem. And here is the output. The first two '>> PrintData' sections are correct and use the singleton as it should be used. The third '>> PrintData' section is by declaring a new variable of TSingleton and creating it. The problem is even though the constructor is declared in the protected section, Free Pascal just gives a compiler warning and it stays public. What is the reason why we may not decrease visibility of methods or properties? Couldn't we add this feature to Free Pascal? Or at least in the ObjFPC mode! Is there another way of implementing a true singleton in Free Pascal, maybe using some other language construct. ----------------------- START Output --------------- [graemeg-linux] singleton > ./singtest
PrintData
hello world ---------
PrintData
hello world hello world 2 ---------
PrintData
----------------------- END Output --------------- -- Graeme Geldenhuys There's no place like S34° 03.168' E018° 49.342'
unit sing; //first singleton {$mode objfpc}{$H+} interface type TSingleton = class private fData : string; protected constructor Create; public procedure PrintData; virtual; end; function GetSingleton : TSingleton; implementation var asing : TSingleton = nil; function GetSingleton : TSingleton; begin if asing = nil then asing := TSingleton.Create; Result := asing; end; constructor TSingleton.Create; begin inherited; fData := 'hello world'; end; procedure TSingleton.PrintData; begin writeln('>> PrintData'); Writeln(fData); end; end.
unit sing2; //second singleton {$mode objfpc}{$H+} interface uses sing; type TSingleton2 = class(TSingleton) private fData2 : string; protected constructor Create; public procedure PrintData; override; end; function GetSingleton2 : TSingleton2; implementation var asing2 : TSingleton2 = nil; function GetSingleton2 : TSingleton2; begin if asing2 = nil then asing2 := TSingleton2.Create; Result := asing2; end; constructor TSingleton2.Create; begin inherited; fData2 := 'hello world 2'; end; procedure TSingleton2.PrintData; begin inherited; Writeln(fData2); end; end.
program singtest; //test program {$mode objfpc}{$H+} uses sing, sing2; var c : char; s: TSingleton; begin GetSingleton.PrintData; WriteLn('---------'); GetSingleton2.PrintData; WriteLn('---------'); s := TSingleton.Create; s.PrintData; s.Free; ReadLn(c); GetSingleton.Free; GetSingleton2.Free; end.
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal