Sign in Join

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

Mailing lists / fpc-pascal / 2016-04

Class vs Object type

16 messages · 10 people · –

Reply by email Subscribe to this list Your subscription

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

Graeme Geldenhuys

Hi,

I use Class and Object data types frequently in my code. I like the fact that Object data types can be used without first instantiating an instance and it gets freed automatically.

But is there a technical (maybe compiler) reason why I should possibly switch all my code to only using Class types for instance?

It has to be said that for more complex "objects" I always use a Class type though. Also, Delphi compatibility (or their lack of Object type support) is of no concern to me.

From the FPC documentation I noted the following:

"The difference between objects and classes is mainly that an object is allocated on the stack, as an ordinary record would be, and that classes are always allocated on the heap."

Are there pros or cons to either?

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp
Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 20 lines
Hi, I use Class and Object data types frequently in my code. I like the fact that Object data types can be used without first instantiating an instance and it gets freed automatically. But is there a technical (maybe compiler) reason why I should possibly switch all my code to only using Class types for instance? It has to be said that for more complex "objects" I always use a Class type though. Also, Delphi compatibility (or their lack of Object type support) is of no concern to me. > From the FPC documentation I noted the following: "The difference between objects and classes is mainly that an object is allocated on the stack, as an ordinary record would be, and that classes are always allocated on the heap." Are there pros or cons to either?

1. Classes are automatically zeroed out. That's an advantage.

2. When doing a:=b (a and B classes) you copy a pointer. This is cheap. when doing the same with objects, you are potentially copying a lot of data, with unknown side effects.

Michael.

Tomas Hajny
to Michael Van Canneyt
Michael Van Canneyt wrote
On Wed, 6 Apr 2016, Graeme Geldenhuys wrote:

Hi,

> I use Class and Object data types frequently in my code. I like the fact > that Object data types can be used without first instantiating an > instance and it gets freed automatically.

.
.

1. Classes are automatically zeroed out. That's an advantage.

True. Note that objects descended from TObject are automatically zeroed out as well as soon as one calls the constructor Init.

2. When doing a:=b (a and B classes) you copy a pointer. This is cheap. when doing the same with objects, you are potentially copying a lot of data, with unknown side effects.

Well, one can work with pointers to objects as well if this is the intention. You should always know whether you want to copy a reference to certain data or whether you want to create copy of the stored data (the latter obviously takes more time, but that doesn't matter much if this is what you need to do anwyay). Otherwise you could equally say that copying just a pointer may have "unknown side effects" as soon as you change the "copy".

Tomas

Sven Barth
to Tomas Hajny
"Tomas Hajny" wrote 7 lines
On Wed, April 6, 2016 13:26, Michael Van Canneyt wrote: > On Wed, 6 Apr 2016, Graeme Geldenhuys wrote: Hi, >> I use Class and Object data types frequently in my code. I like the

fact

Show quoted text 8 lines
>> that Object data types can be used without first instantiating an >> instance and it gets freed automatically. . . > 1. Classes are automatically zeroed out. That's an advantage. True. Note that objects descended from TObject are automatically zeroed out as well as soon as one calls the constructor Init.

Just for clarification (cause I first thought wrong as well): this means the TObject object from unit Objects, instead of the class TObject.

Regards,
Sven

Sven Barth
to Graeme Geldenhuys: I use Class and Object data types frequently in my code. I like the fact that Object data…

Am 06.04.2016 13:23 schrieb "Graeme Geldenhuys" <

Show quoted text 7 lines
: Hi, I use Class and Object data types frequently in my code. I like the fact that Object data types can be used without first instantiating an instance and it gets freed automatically.

Note: with the modeswitch advandedrecords you can also use methods in records which allows you to declare operator overloads that can also be picked up by generics. (Just in case you'd need it)

Regards,
Sven

Vojtěch Čihák
to Tomas Hajny: . . True. Note that objects descended from TObject are automatically zeroed out as well…

How can I do it?
 
When I try do:
 
TMyObj = object(TObject)
 
compiler tells me:
 
Error: The mix of different kind of objects (class, object, interface, etc) isn't allowed  
Thanks
 
V.
______________________________________________________________

Show quoted text 5 lines
Od: Tomas Hajny Komu: "FPC-Pascal users discussions" Datum: 06.04.2016 14:07 Předmět: Re: [fpc-pascal] Class vs Object type
Michael Van Canneyt wrote
On Wed, 6 Apr 2016, Graeme Geldenhuys wrote:

True. Note that objects descended from TObject are automatically zeroed out as well as soon as one calls the constructor Init.

Tomas

Tomas Hajny
to Vojtěch Čihák
Vojtěch Čihák wrote 10 lines
How can I do it?   When I try do:   TMyObj = object(TObject)   compiler tells me:   Error: The mix of different kind of objects (class, object, interface, etc) isn't allowed

You need to add unit Objects to the uses clause (see also the e-mail from Sven).

Tomas

Show quoted text 13 lines
______________________________________________________________ > Od: Tomas Hajny > Komu: "FPC-Pascal users discussions" > Datum: 06.04.2016 14:07 > Předmět: Re: [fpc-pascal] Class vs Object type > On Wed, April 6, 2016 13:26, Michael Van Canneyt wrote: > On Wed, 6 Apr 2016, Graeme Geldenhuys wrote: True. Note that objects descended from TObject are automatically zeroed out as well as soon as one calls the constructor Init. Tomas
Dennis
to Tomas Hajny
objects unit contains
    TObject = OBJECT
       CONSTRUCTOR Init;
       PROCEDURE Free;
       FUNCTION Is_Object(P:Pointer):Boolean;
       DESTRUCTOR Done;  Virtual;
    END;

On the other hand, objpash.inc contains
TObject = class

        public
           { please don't change the order of virtual methods, because
             their vmt offsets are used by some assembler code which uses
             hard coded addresses (FK)                                 }
           constructor Create;
          .....

That is so confusing.
What are other real benefits in inheriting from object unit's TObject?

The zeroing function of init can easily be achieved by copying the code to the user's object init constructor:

CONSTRUCTOR TObject.Init;
VAR LinkSize: LongInt; Dummy: DummyObject;
BEGIN
    LinkSize := Pbyte(@Dummy.Data)-Pbyte(@Dummy);  { Calc VMT link size }
    FillChar((Pbyte(@Self)+LinkSize)^,
      SizeOf(Self)-LinkSize, #0);                      { Clear data fields }
END;

Dennis

Tomas Hajny wrote 33 lines
On Wed, April 6, 2016 15:13, Vojtěch Čihák wrote: > How can I do it? > > When I try do: > > TMyObj = object(TObject) > > compiler tells me: > > Error: The mix of different kind of objects (class, object, interface, > etc) isn't allowed You need to add unit Objects to the uses clause (see also the e-mail from Sven). Tomas > ______________________________________________________________ >> Od: Tomas Hajny >> Komu: "FPC-Pascal users discussions" >> Datum: 06.04.2016 14:07 >> Předmět: Re: [fpc-pascal] Class vs Object type >> > On Wed, April 6, 2016 13:26, Michael Van Canneyt wrote: >> On Wed, 6 Apr 2016, Graeme Geldenhuys wrote: > True. Note that objects descended from TObject are automatically zeroed > out as well as soon as one calls the constructor Init. > > Tomas _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Sven Barth
to Dennis
"Dennis" wrote 21 lines
objects unit contains TObject = OBJECT CONSTRUCTOR Init; PROCEDURE Free; FUNCTION Is_Object(P:Pointer):Boolean; DESTRUCTOR Done; Virtual; END; On the other hand, objpash.inc contains TObject = class public { please don't change the order of virtual methods, because their vmt offsets are used by some assembler code which uses hard coded addresses (FK) } constructor Create; ..... That is so confusing. What are other real benefits in inheriting from object unit's TObject?

It's mainly there for backwards compatibility with TP code. It's also the base class of the FV object hierarchy.

Regards,
Sven

Graeme Geldenhuys
to Graeme Geldenhuys: I use Class and Object data types frequently in my code. I like the fact that Object data…
Graeme Geldenhuys wrote
Are there pros or cons to either?

Thanks for the replies everybody. From the answers I've seen thus far I came to the conclusion that if the code which uses Object style objects works, there is no real reason or urgency to port that code to Class style objects. No technical or performance related good to know, thanks.

Regards,
- Graeme -

Peter
to Graeme Geldenhuys: I use Class and Object data types frequently in my code. I like the fact that Object data…
Graeme Geldenhuys wrote 14 lines
Hi, ....... >From the FPC documentation I noted the following: "The difference between objects and classes is mainly that an object is allocated on the stack, as an ordinary record would be, and that classes are always allocated on the heap." Are there pros or cons to either? Regards, - Graeme -

Hi Graeme,

A comment re stack vs heap on Linux.
Using a recursive routine, I discovered the hard way that

1) the stack is surprisingly small by default (8192Kb)
2) the stack blow error message "broken pipe" is rather unintuitive

The stack may be set to be unlimited (I've done this now), but this is not usually the default setting.

Regarding the 2nd point, the kernel sends a signal to a process with a blown stack, but signal processing requires stack space! This might be fixable by directing the process to use the alternate stack for signal handling. The error message would hopefully then be more meaningful.

Regards,
Peter

Santiago A.
to Graeme Geldenhuys: I use Class and Object data types frequently in my code. I like the fact that Object data…
Graeme Geldenhuys wrote 8 lines
"The difference between objects and classes is mainly that an object is allocated on the stack, as an ordinary record would be, and that classes are always allocated on the heap." Are there pros or cons to either? Regards, - Graeme -

A nice pro of objects is that, if you don't need a constructor, you can forget about calling create and free.

If you need a constructor (ie it has virtual methods), there is not that advantage.

Moreover, if the object uses classes instances that must be freed, you also must call destructor, then any advantage is over. Maybe a little performance gain using stack instead of heap.

A nice feature would be default creator and destructor:

ej.

type
  TMyObject=Object
    constructor default;
    Destructor default;
  end;
procedure foo;
var
 obj:TMyObject;
begin
  // Default constructor (if it has) automatically called here
  obj.xxxx;
  obj.zzz;
  // Default destructor automatically called here
end;

Or even with parameters

type
 TMyObjectParam=Object
   constructor default(n:Integer);
   Destructor default;
 end;
procedure foo;
var
 obj1:TMyObjectParam(7);
 obj2:TMyObjectParam;
begin
 // Default constructor of obj1 automatically called here with param 7
 // Default constructor of obj2 not called because the declaration has no parameters
 obj1.xxxx;
 obj1.zzz;
 if condition then begin
   obj2.Default(x); // Constructor must be called manually
   obj2.xxxx;
   obj2.zzz;
 end;
 // Default destructor of obj2 automatically called here if it has been initializated
 // Default destructor of obj1 automatically called here
end;
Saludos Santi
Graeme Geldenhuys
to Santiago A.
Santiago A. wrote
Moreover, if the object uses classes instances that must be freed, you also must call destructor, then any advantage is over.

Technically yes, but as a rule of thumb, I *never* use Class objects inside an Object object. That just seems messy.

Regards,
- Graeme -

Santiago A.
to Graeme Geldenhuys
Graeme Geldenhuys wrote 5 lines
On 2016-04-07 11:58, Santiago A. wrote: > Moreover, if the object uses classes instances that must be freed, you > also must call destructor, then any advantage is over. Technically yes, but as a rule of thumb, I *never* use Class objects inside an Object object. That just seems messy.

Usually, me neither.

But I often use open arrays that can grow. Although open arrays are pointers that use heap, they are supposed to be liberated when the object is removed from stack, but in fpc 2.6.4 didn't properly. and 3.0.0 I have found strange behaviors and errors if I don't call a constructor.

Nevertheless, I stick on my idea that even if objects have virtual methods, they should be initializated properly even if you don't call the constructor.

Saludos Santi
Adriaan van Os
to Graeme Geldenhuys: I use Class and Object data types frequently in my code. I like the fact that Object data…
Graeme Geldenhuys wrote
Are there pros or cons to either?

The fashion of the day. Apparently, programmers are (supposed to be) not intelligent enough to work with pointers themselves -- if needed. So the compiler does that for you and declares everything a pointer automatically. Same with "magic" types such as PChar and "AnsiString". Poor man's programming in my view, but as said, that's the fashion of the day.

Needless to say that a program where the programmer does have full control himself (and uses that to the advantage) is both faster and more reliable than a program where things are handled "automagically".

Regards,

Adriaan van Os

Richard Ward

<<Paraphrasing Graeme’s and other’s previous emails. Please refer to the posted emails and all the responses if you need to.>>

Show quoted text 10 lines
I use Class and Object data types frequently in my code. I like the fact that Object data types can be used without first instantiating an instance and it gets freed automatically. <snip> It has to be said that for more complex "objects" I always use a Class type though. Also, Delphi compatibility (or their lack of Object type support) is of no concern to me. <snip> Are there pros or cons to either?

When I first decided to explore OOP in FPC, I (as well as most others) discovered that FPC supported two different Object models and wondered the same. In those days I had some free time to explore and ended up creating a Free Pascal Wiki article :

http://wiki.freepascal.org/Programming_Using_Objects Programming Using Objects - Free Pascal wiki <http://wiki.freepascal.org/Programming_Using_Objects>

Unfortunately I ran out of time and never got to the Class based version. I started out liking the Object model for exactly the same reason you state, due to the simpler overhead of not having to “worry” as much about memory leak and initialization coding. In short, I abandoned the Object model since most of the FPC support was for the Class model and mixing Class and Object models in the same code base can get confusing resulting in more types of bugs and increased time spent maintaining stuff. Also, there are other (sometimes subtle) differences in how the Object and Class models are implemented. For production code, my opinion is to avoid mixing models.

There was an offshoot discussion about reference vs. value types and your original comment above seems to be a common general consensus that one gravitates towards value types for simple structures and class (reference) types for more complex information where “identity” aspects are considered. About two years ago, I decided I needed to learn another language and started exploring Ruby and Python. About 3 months after surveying those languages, Apple unveiled Swift and I decided I would bite the bullet and delve into it. If anyone wants to hear summaries of what I have learned, I would be happy to take a discussion over to FPC-other or private email.

I mention my extended Swift dalliance here because one of the major internal dichotomies in the Swift language itself is reference vs value languages constructs superimposed with mutable and immutable keywords. You may find the following article helpful which discusses how to determine when to use value vs. reference types. It uses Swift examples but the analysis is generic.

Should I use a Swift struct or a class?
http://faq.sealedabstract.com/structs_or_classes/ <http://faq.sealedabstract.com/structs_or_classes/>

-Richard