Re: [fpc-pascal] WHY compiler should be public?
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?
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?
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 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/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/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?
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?
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