Re: [fpc-pascal] WHY compiler should be public?

2013-10-27 Thread Michael Van Canneyt



On Sun, 27 Oct 2013, Xiangrong Fang wrote:


2013/10/25 Michael Van Canneyt mich...@freepascal.org
  Why not simply make it a procedure that is called by ver-2 and ver-3.

If it cannot be called directly from external code, and will called only from 
inside a visible consructor, there is simply no reason to make this procedure a 
constructor. A simple procedure will do.


​Because I don't know how to make it non-constructor. See the following code:

  1 unit wtree;
  2 {$mode objfpc}{$H+}
  3 interface
  4 uses tree;
  5 type
  6   TQWordTree = specialize TTreeQWord;
  7   TWTree = class(TQWordTree)
  8   private
  9 FModel: string;
 10   public
 11 property Model: string read FModel;
 12 constructor Create(AData: QWord; AParent: TWTree; AModel: string);
 13 constructor Create(HeadNode, TailNode: QWord);
 14   end;
 15 implementation
 16
 17 constructor TWTree.Create(AData: QWord; AParent: TWTree; AModel: string);
 18 begin
 19   inherited Create(AData, AParent);
 20   FModel := AModel;
 21 end;
 22
 23 constructor TWTree.Create(HeadNode, TailNode: QWord);
 24 begin
 25   inherited Create(0, nil);
 26   Data := HeadNode;
 27   with TWTree do Create(TailNode, Create(HeadNode, Self, 'h'), 't');
 28   FModel := 'R';
 29 end;
 30
 31 end.

Please tell me how to deal with line 27, which called the should-be-private 
constructor.


Ah. The 'private' constructor is called FROM ANOTHER INSTANCE. You didn't say 
that.

That currently can't be done.

Michael.



BTW, this code uses TTree class, which is here:

https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas

Also,
​ ​I don't understand why this does not work:

f := TFileStream.Create;

I know that TFileStream's Create require a file name parameter, but as 
TFileStream is inherited from TObject, which has a Create without parameter.  
This is why I feel that it is possible to HIDE a public
constructor from ancestor.


I think this is a bug :)

Michael.___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] WHY compiler should be public?

2013-10-27 Thread Sven Barth
Am 27.10.2013 12:18 schrieb Michael Van Canneyt mich...@freepascal.org:
 Also,
  I don't understand why this does not work:

 f := TFileStream.Create;

 I know that TFileStream's Create require a file name parameter, but as
TFileStream is inherited from TObject, which has a Create without
parameter.  This is why I feel that it is possible to HIDE a public
 constructor from ancestor.


 I think this is a bug :)

No, I don't think so. If you want users to use the original constructor as
well you'd need to declare yours as overload. If it would be possible to
call TFileStream.Create without parameters then the instance would be in an
inconsistent state, so only calling the constructor with arguments should
be possible (which is the case for TFileStream.

So this is definitely by design.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] WHY compiler should be public?

2013-10-27 Thread Sven Barth
Am 27.10.2013 02:12 schrieb Xiangrong Fang xrf...@gmail.com:
 Also, 

 I don't understand why this does not work:

 f := TFileStream.Create;

 I know that TFileStream's Create require a file name parameter, but as
TFileStream is inherited from TObject, which has a Create without
parameter.  This is why I feel that it is possible to HIDE a public
constructor from ancestor.

Yes, it's possible to hide a public constructor (or any method for that
matter), but it's not possible to decrease the visibility of a constructor
(or any method for that.matter).

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] WHY compiler should be public?

2013-10-27 Thread Xiangrong Fang
2013/10/27 Michael Van Canneyt mich...@freepascal.org



 Ah. The 'private' constructor is called FROM ANOTHER INSTANCE. You didn't
 say that.

 That currently can't be done.

 Michael.


​So, in this case, can/should I make my constructor private, ignoring the
warning, or just make it public to play it safe?

Regards,
Xiangrong​
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] WHY compiler should be public?

2013-10-26 Thread Xiangrong Fang
2013/10/25 Michael Van Canneyt mich...@freepascal.org

 Why not simply make it a procedure that is called by ver-2 and ver-3.

 If it cannot be called directly from external code, and will called only
 from inside a visible consructor, there is simply no reason to make this
 procedure a constructor. A simple procedure will do.


​Because I don't know how to make it non-constructor. See the following
code:

  1 unit wtree;
  2 {$mode objfpc}{$H+}
  3 interface
  4 uses tree;
  5 type
  6   TQWordTree = specialize TTreeQWord;
  7   TWTree = class(TQWordTree)
  8   private
  9 FModel: string;
 10   public
 11 property Model: string read FModel;
 12 constructor Create(AData: QWord; AParent: TWTree; AModel: string);
 13 constructor Create(HeadNode, TailNode: QWord);
 14   end;
 15 implementation
 16
 17 constructor TWTree.Create(AData: QWord; AParent: TWTree; AModel:
string);
 18 begin
 19   inherited Create(AData, AParent);
 20   FModel := AModel;
 21 end;
 22
 23 constructor TWTree.Create(HeadNode, TailNode: QWord);
 24 begin
 25   inherited Create(0, nil);
 26   Data := HeadNode;
 27   with TWTree do Create(TailNode, Create(HeadNode, Self, 'h'), 't');
 28   FModel := 'R';
 29 end;
 30
 31 end.

Please tell me how to deal with line 27, which called the should-be-private
constructor.

BTW, this code uses TTree class, which is here:

https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas

Also, ​

​I don't understand why this does not work:

f := TFileStream.Create;

I know that TFileStream's Create require a file name parameter, but as
TFileStream is inherited from TObject, which has a Create without
parameter.  This is why I feel that it is possible to HIDE a public
constructor from ancestor.

Best Regards,
Xiangrong​
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] WHY compiler should be public?

2013-10-26 Thread Xiangrong Fang
2013/10/25 Michael Van Canneyt mich...@freepascal.org

 Why not simply make it a procedure that is called by ver-2 and ver-3.

 If it cannot be called directly from external code, and will called only
 from inside a visible consructor, there is simply no reason to make this
 procedure a constructor. A simple procedure will do.


​Because I don't know how to make it non-constructor. See the following
code:

  1 unit wtree;
  2 {$mode objfpc}{$H+}
  3 interface
  4 uses tree;
  5 type
  6   TQWordTree = specialize TTreeQWord;
  7   TWTree = class(TQWordTree)
  8   private
  9 FModel: string;
 10   public
 11 property Model: string read FModel;
 12 constructor Create(AData: QWord; AParent: TWTree; AModel: string);
 13 constructor Create(HeadNode, TailNode: QWord);
 14   end;
 15 implementation
 16
 17 constructor TWTree.Create(AData: QWord; AParent: TWTree; AModel:
string);
 18 begin
 19   inherited Create(AData, AParent);
 20   FModel := AModel;
 21 end;
 22
 23 constructor TWTree.Create(HeadNode, TailNode: QWord);
 24 begin
 25   inherited Create(0, nil);
 26   Data := HeadNode;
 27   with TWTree do Create(TailNode, Create(HeadNode, Self, 'h'), 't');
 28   FModel := 'R';
 29 end;
 30
 31 end.

Please tell me how to deal with line 27, which called the should-be-private
constructor.

BTW, this code uses TTree class, which is here:

https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas

Also, ​

​I don't understand why this does not work:

f := TFileStream.Create;

I know that TFileStream's Create require a file name parameter, but as
TFileStream is inherited from TObject, which has a Create without ​
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] WHY compiler should be public?

2013-10-25 Thread Michael Van Canneyt



On Fri, 25 Oct 2013, Xiangrong Fang wrote:


Hi,

First of all, I did some research and found this:

http://free-pascal-general.1045716.n5.nabble.com/Compiler-Warning-Constructor-should-be-public-td2825747.html

But that did not convince me. So here is my situation and question.

I have the following case:

TBase = class
public
  constructor Create; //VER-0
end;

TDerived = class(TBase)
private
  constructor Create(param1); //VER-1 
public
  constructor Create; reintroduce;    //VER-0'
  constructor Create(param1, param2); //VER-2
  constructor Create(param1, param2, param3); //VER-3
end;

My purpose is that while using TDerived, only VER-2
and VER-3 of the constructors should be used, VER-0
and VER-1 are used INTERNALLY by VER-2 and VER-3 and
should NOT be used publicly.


Why not simply make it a procedure that is called by ver-2 and ver-3.

If it cannot be called directly from external code, and will called only 
from inside a visible consructor, there is simply no reason to make this 
procedure a constructor. A simple procedure will do.


Michael.___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

[fpc-pascal] WHY compiler should be public?

2013-10-24 Thread Xiangrong Fang
Hi,

First of all, I did some research and found this:

http://free-pascal-general.1045716.n5.nabble.com/Compiler-Warning-Constructor-should-be-public-td2825747.html

But that did not convince me. So here is my situation and question.

I have the following case:

TBase = class
public
  constructor Create; //VER-0
end;

TDerived = class(TBase)
private
  constructor Create(param1); //VER-1
public
  constructor Create; reintroduce;//VER-0'
  constructor Create(param1, param2); //VER-2
  constructor Create(param1, param2, param3); //VER-3
end;

My purpose is that while using TDerived, only VER-2
and VER-3 of the constructors should be used, VER-0
and VER-1 are used INTERNALLY by VER-2 and VER-3 and
should NOT be used publicly.

As restricted by the rule of OOP, you cannot make a
method which is public in base class private in descendants,
I plan to do the following:

1) reintroduce a Create (without param), which just throw
an exception explaining that this MUST NOT be called directly.
Meanwhile, use inherited Create internally in other versions
of the constructors.

2) Make VER-1 private so that it cannot be called outside.

Now the compiler throw a warning that constructor should be
public.

In the post I referred, Graeme explained that:

==
Your code is flawed. Object Pascal is quite clear regarding
visibility rules. TObject has a Public constructor. You can
only raise the visibility from there, not reduce visibility.

Imagine how confusing it will be if you code was a library
of some sorts and other developers had to use it. In a
inherited class, you have public visibility to the constructor
or some other method, and then suddenly in the descendant class
the methods are hidden from the developer??  Not a good idea.
==

I don't understand this, because to me, the VER-1 constructor is
introduced in TDerived, make it non-public does NOT reduce the
visibility of VER-0 constructor, hence is not a violation of
visibility rules, is it???

Thanks!
Xiangrong
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal