Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-01

Check if an abstract method is implemented or not

9 messages · 6 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

xrfang

Hi All,

I wrote a TPainter abstract class, and a TPaintRect class. ?In the TPaintRect class I have this code:

procedure TPaintRect.OnMouseEnter(Sender: TObject);
var
? i: Integer;
? p: TPainter;
begin
? for i := 0 to painters.Count - 1 do begin
? ? p := TPainter(painters.Objects[i]);
? ? try
? ? ? p.OnMouseEnter(Sender);
? ? except on EAbstractError do ; end;
? end;
? if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender);
end;

While running in IDE, the program will crash because OnMouseEnter is abstract.

My problems are:

1) As I already wrapped it with try-except, I hope it won't trigger IDE exception. But even I turn off "Notify on Lazarus Exception" in debugger options it still pops up, and the popup said RunError(211), NOT EAbstractError. ?The program runs well outside of IDE.

2) Is there a way to detect if an abstract method is implemented or not, without trying to call it and try...except?

Thanks,
Shannon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130124/91a44110/attachment.html>

Reply by email

Fei Valentain
to xrfang

Hi, I don't test it in fp. But in Delphi I just create virtual method with empty body in this situation.
24.01.2013 15:11 ???????????? "xrfang" ???????:

Show quoted text 44 lines
Hi All, I wrote a TPainter abstract class, and a TPaintRect class. In the TPaintRect class I have this code: procedure TPaintRect.OnMouseEnter(Sender: TObject); var i: Integer; p: TPainter; begin for i := 0 to painters.Count - 1 do begin p := TPainter(painters.Objects[i]); try p.OnMouseEnter(Sender); except on EAbstractError do ; end; end; if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender); end; While running in IDE, the program will crash because OnMouseEnter is abstract. My problems are: 1) As I already wrapped it with try-except, I hope it won't trigger IDE exception. But even I turn off "Notify on Lazarus Exception" in debugger options it still pops up, and the popup said RunError(211), NOT EAbstractError. The program runs well outside of IDE. 2) Is there a way to detect if an abstract method is implemented or not, without trying to call it and try...except? Thanks, Shannon -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130124/87fdbb16/attachment-0001.html>

Reply by email

Michael Van Canneyt
to xrfang: I wrote a TPainter abstract class, and a TPaintRect class. ?In the TPaintRect class I…
xrfang wrote 25 lines
Hi All, I wrote a TPainter abstract class, and a TPaintRect class. ?In the TPaintRect class I have this code: procedure TPaintRect.OnMouseEnter(Sender: TObject); var ? i: Integer; ? p: TPainter; begin ? for i := 0 to painters.Count - 1 do begin ? ? p := TPainter(painters.Objects[i]); ? ? try ? ? ? p.OnMouseEnter(Sender); ? ? except on EAbstractError do ; end; ? end; ? if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender); end; While running in IDE, the program will crash because OnMouseEnter is abstract. My problems are: 1) As I already wrapped it with try-except, I hope it won't trigger IDE exception. But even I turn off "Notify on Lazarus Exception" in debugger options it still pops up, and the popup said RunError(211), NOT EAbstractError. ?The program runs well outside of IDE. 2) Is there a way to detect if an abstract method is implemented or not, without trying to call it and try...except?

The following will do it:

uses sysutils;
Type
   TParent = Class
     Procedure MyMethod; virtual; abstract;
   end;
   TChild = class(TParent)
   end;
var
   C : TParent;
begin
   c:=TChild.Create;
   If TMethod(@C.MyMethod).Code=Pointer(@system.AbstractError) then
     Writeln('Not implemented')
   else
     Writeln('Implemented')
end.

When run, it will print 'Not implemented'.

But you should not instantiate objects with abstract methods to begin with.

The compiler warns you if you do.
(compile the above program with warnings/hints to see it)

Michael.

Reply by email

Xiangrong Fang
to Michael Van Canneyt: The following will do it: uses sysutils; Type TParent = Class Procedure MyMethod;…

This is a clean solution. And as a matter of fact, the compiler does NOT warn me while instantiate class with abstract method. This is different than Java, in which you must implement all abstract method while inherits from an abstract class.

Why I shall not instantiate a sub-class that has not fully implemented abstract methods of its parent class?

Thanks!
Shannon

2013/1/24 Michael Van Canneyt

Show quoted text 75 lines
On Thu, 24 Jan 2013, xrfang wrote: Hi All, > I wrote a TPainter abstract class, and a TPaintRect class. In the > TPaintRect class I have this code: > > procedure TPaintRect.OnMouseEnter(**Sender: TObject); > var > i: Integer; > p: TPainter; > begin > for i := 0 to painters.Count - 1 do begin > p := TPainter(painters.Objects[i]); > try > p.OnMouseEnter(Sender); > except on EAbstractError do ; end; > end; > if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender); > end; > > While running in IDE, the program will crash because OnMouseEnter is > abstract. > > My problems are: > > 1) As I already wrapped it with try-except, I hope it won't trigger IDE > exception. But even I turn off "Notify on Lazarus Exception" in debugger > options it > still pops up, and the popup said RunError(211), NOT EAbstractError. The > program runs well outside of IDE. > > 2) Is there a way to detect if an abstract method is implemented or not, > without trying to call it and try...except? > The following will do it: uses sysutils; Type TParent = Class Procedure MyMethod; virtual; abstract; end; TChild = class(TParent) end; var C : TParent; begin c:=TChild.Create; If TMethod(@C.MyMethod).Code=**Pointer(@system.AbstractError) then Writeln('Not implemented') else Writeln('Implemented') end. When run, it will print 'Not implemented'. But you should not instantiate objects with abstract methods to begin with. The compiler warns you if you do. (compile the above program with warnings/hints to see it) Michael. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130124/f5e1c7d5/attachment.html>

Reply by email

Michael Van Canneyt
to Xiangrong Fang
Xiangrong Fang wrote
This is a clean solution. And as a matter of fact, the compiler does NOT warn me while instantiate class with abstract method.??

It definitely does, unless you use a class pointer to do it of course.

In the below example:

   TParentClass = Class of TParent;
Var
   PC : TParentClass;
begin
   PC:=TChild;
   C:=PC.Create;
end;

You will not get a warning. But if you run the example as I described it, you get:

home: >fpc -S2 -vwh te.pp
te.pp(15,19) Warning: Constructing a class "TChild" with abstract method "MyMethod"
te.pp(5,15) Hint: Found abstract method: procedure MyMethod(<TParent>);
Show quoted text 5 lines
This is different than Java, in which you must implement all abstract method while inherits from an abstract class. Why I shall not instantiate a sub-class that has not fully implemented abstract methods of its parent class?

Obviously:
Because then you run the risk that you try to execute a method that is not implemented.

Michael.

Show quoted text 78 lines
Thanks! Shannon 2013/1/24 Michael Van Canneyt On Thu, 24 Jan 2013, xrfang wrote: Hi All, I wrote a TPainter abstract class, and a TPaintRect class. ?In the TPaintRect class I have this code: procedure TPaintRect.OnMouseEnter(Sender: TObject); var ? i: Integer; ? p: TPainter; begin ? for i := 0 to painters.Count - 1 do begin ? ? p := TPainter(painters.Objects[i]); ? ? try ? ? ? p.OnMouseEnter(Sender); ? ? except on EAbstractError do ; end; ? end; ? if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender); end; While running in IDE, the program will crash because OnMouseEnter is abstract. My problems are: 1) As I already wrapped it with try-except, I hope it won't trigger IDE exception. But even I turn off "Notify on Lazarus Exception" in debugger options it still pops up, and the popup said RunError(211), NOT EAbstractError. ?The program runs well outside of IDE. 2) Is there a way to detect if an abstract method is implemented or not, without trying to call it and try...except? The following will do it: uses sysutils; Type ? TParent = Class ? ? Procedure MyMethod; virtual; abstract; ? end; ? TChild = class(TParent) ? end; var ? C : TParent; begin ? c:=TChild.Create; ? If TMethod(@C.MyMethod).Code=Pointer(@system.AbstractError) then ? ? Writeln('Not implemented') ? else ? ? Writeln('Implemented') end. When run, it will print 'Not implemented'. But you should not instantiate objects with abstract methods to begin with. The compiler warns you if you do. (compile the above program with warnings/hints to see it) Michael. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Xiangrong Fang
to Michael Van Canneyt

Sorry I overlooked the message. Complie DO emit warnings.

As the use of sub-class is well controlled, I will check in every place the abstract method is called, so this is ok for me.

Thanks a lot.

2013/1/24 Michael Van Canneyt

Show quoted text 138 lines
On Thu, 24 Jan 2013, Xiangrong Fang wrote: This is a clean solution. And as a matter of fact, the compiler does NOT > warn me while instantiate class with abstract method. > It definitely does, unless you use a class pointer to do it of course. In the below example: TParentClass = Class of TParent; Var PC : TParentClass; begin PC:=TChild; C:=PC.Create; end; You will not get a warning. But if you run the example as I described it, you get: home: >fpc -S2 -vwh te.pp te.pp(15,19) Warning: Constructing a class "TChild" with abstract method "MyMethod" te.pp(5,15) Hint: Found abstract method: procedure MyMethod(<TParent>); This is different than Java, > in which you must implement all abstract method while inherits from an > abstract class. > > Why I shall not instantiate a sub-class that has not fully implemented > abstract methods of its parent class? > Obviously: Because then you run the risk that you try to execute a method that is not implemented. Michael. > Thanks! > Shannon > > > 2013/1/24 Michael Van Canneyt > > > On Thu, 24 Jan 2013, xrfang wrote: > > Hi All, > I wrote a TPainter abstract class, and a TPaintRect class. > In the TPaintRect class I have this code: > > procedure TPaintRect.OnMouseEnter(**Sender: TObject); > var > i: Integer; > p: TPainter; > begin > for i := 0 to painters.Count - 1 do begin > p := TPainter(painters.Objects[i]); > try > p.OnMouseEnter(Sender); > except on EAbstractError do ; end; > end; > if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender); > end; > > While running in IDE, the program will crash because > OnMouseEnter is abstract. > > My problems are: > > 1) As I already wrapped it with try-except, I hope it won't > trigger IDE exception. But even I turn off "Notify on Lazarus Exception" in > debugger options it > still pops up, and the popup said RunError(211), NOT > EAbstractError. The program runs well outside of IDE. > > 2) Is there a way to detect if an abstract method is > implemented or not, without trying to call it and try...except? > > > The following will do it: > > uses sysutils; > > Type > TParent = Class > Procedure MyMethod; virtual; abstract; > end; > > TChild = class(TParent) > end; > > var > C : TParent; > > begin > c:=TChild.Create; > If TMethod(@C.MyMethod).Code=**Pointer(@system.AbstractError) then > Writeln('Not implemented') > else > Writeln('Implemented') > end. > > When run, it will print 'Not implemented'. > > But you should not instantiate objects with abstract methods to begin > with. > > The compiler warns you if you do. > (compile the above program with warnings/hints to see it) > > Michael. > -- > ______________________________**_________________ > Lazarus mailing list > .**freepascal.org > http://lists.lazarus.**freepascal.org/mailman/**listinfo/lazarus<http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus> > > > > -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130124/363a9912/attachment-0001.html>

Reply by email

Mattias Gaertner
to Xiangrong Fang: This is a clean solution. And as a matter of fact, the compiler does NOT warn me while…

Xiangrong Fang hat am 24. Januar 2013 um 14:03 geschrieben:

This is a clean solution. And as a matter of fact, the compiler does NOT warn me while instantiate class with abstract method.

Normally the compiler warns for each abstract method. For example, this creates 5 warnings:
TStrings.Create;
If not then please create a bug report.

Show quoted text 5 lines
This is different than Java, in which you must implement all abstract method while inherits from an abstract class. Why I shall not instantiate a sub-class that has not fully implemented abstract methods of its parent class?

Well, you can shoot yourself in the foot. ;)

Mattias

Reply by email

Xiangrong Fang
to Mattias Gaertner

One more report:

I finally decided to use the solution suggested by Fei, i.e. empty method in base class instead of Abstract method. Becuase comparing address to @system.AbstractError caused trouble if I put my class into a shared library.

Thanks.

2013/1/24 Mattias Gaertner

Show quoted text 32 lines
Xiangrong Fang hat am 24. Januar 2013 um 14:03 geschrieben: > This is a clean solution. And as a matter of fact, the compiler does NOT warn > me while instantiate class with abstract method. Normally the compiler warns for each abstract method. For example, this creates 5 warnings: TStrings.Create; If not then please create a bug report. > This is different than Java, in which you must implement all abstract method > while inherits from an abstract class. > > Why I shall not instantiate a sub-class that has not fully implemented > abstract methods of its parent class? Well, you can shoot yourself in the foot. ;) Mattias -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20130124/97cbb36e/attachment.html>

Reply by email