On Wednesday 11 November 2009 09:22:30 Graeme Geldenhuys wrote:
> Flávio Etrusco wrote:
> > Graeme, I guess the OP didn't want to reintroduce the 'Create'
> > constructor with lower visibility, just implement a second constructor
> > with private visiblity.
> > It can be useful when implementing singletons and factories to avoid
> > some types of misuse by an unattentive coworker...
> The problem is that a constructor (in this case Create) in still always
> public. So that unattentive coworker can very easily use the default
> "public" Create() constructor and by-pass all your custom code in your
> "private" constructor.

Just a thought:

In FP, as with Delphi, TObject is the ultimate ancestor. Would it be possible 
to add a modified version of TObject to the RTL where a default constructor 
is not defined?

I know that TObject has a lot of functionality but would it be possible for a 
user-defined class to be defined without having to inherit from anything? A 
sort of user-defined TObject?

> So that pretty much makes your custom private constructor useless. Plus
> if the class was instantiated with the default public Create(), there
> could be many other side-effects due to the fact that it by-passed your
> custom code.
> And yes I know, such a feature would be very handy for Singleton
> implementations, but alternative solutions are possible. The same could
> be applied to the original poster's code, without creating private or
> protected constructors.
> A very quick and dirty solution would be to reimplement the public
> Create() constructor and immediately raise an exception inside it,
> explaining the problem. That way if any developer tries to use that
> default constructor, they will get an error - instead of some silent
> side-effect later on. Then implement a new public custom constructor
> with your desired code.
> eg:
>   TMyClass = class(TObject)
>   public
>     constructor Create;
>     constructor CreateCustom(param1: string);
>   end;
> ...
>   constructor TMyClass.Create;
>   begin
>     raise Exception.Create('Please use CreateCustom instead');
>   end;
>   constructor TMyClass.CreateCustom(param1: string);
>   begin
>     inherited Create; // <- note inherited call to bypass Exception
>     FValue := param1;
>     ....
>   end;
> No private or protected constructors are used and you are guiding the
> developer to only use the CreatCustom constructor, ensuring your custom
> code is executed.
> This is still not a perfect solution, but minimized the potential problems.
> > IIRC the last time this issue was raised you were on the side for
> > removing the warning - my opinion too ;-)
> Maybe I learnt from my mistakes. ;-)
> Regards,
>   - Graeme -

fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org

Reply via email to