Class vs Object type

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

Class vs Object type

Graeme Geldenhuys-6
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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Michael Van Canneyt


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.
>
> 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.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Tomas Hajny-2
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
>> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Sven Barth-2

Am 06.04.2016 14:06 schrieb "Tomas Hajny" <[hidden email]>:
>
> 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
> >> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Sven Barth-2
In reply to this post by Graeme Geldenhuys-6

Am 06.04.2016 13:23 schrieb "Graeme Geldenhuys" <[hidden email]>:
>
> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

vojtech.cihak
In reply to this post by Tomas Hajny-2

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.

______________________________________________________________
> Od: Tomas Hajny <[hidden email]>
> Komu: "FPC-Pascal users discussions" <[hidden email]>
> 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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Tomas Hajny-2
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 <[hidden email]>
>> Komu: "FPC-Pascal users discussions" <[hidden email]>
>> 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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Dennis
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:

> 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 <[hidden email]>
>>> Komu: "FPC-Pascal users discussions" <[hidden email]>
>>> 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  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Sven Barth-2

Am 06.04.2016 16:28 schrieb "Dennis" <[hidden email]>:
>
> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Graeme Geldenhuys-6
In reply to this post by Graeme Geldenhuys-6
On 2016-04-06 12:23, 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 reasons at least.
Very good to know, thanks.


Regards,
  - Graeme -

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Peter
In reply to this post by Graeme Geldenhuys-6
On 06/04/16 12:23, Graeme Geldenhuys wrote:

> 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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Santiago A.
In reply to this post by Graeme Geldenhuys-6
El 06/04/2016 a las 13:23, Graeme Geldenhuys escribió:
> "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
[hidden email]

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Graeme Geldenhuys-6
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.

Regards,
  - Graeme -

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Santiago A.
El 07/04/2016 a las 13:04, Graeme Geldenhuys escribió:
> 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
[hidden email]

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Adriaan van Os-2
In reply to this post by Graeme Geldenhuys-6
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Class vs Object type

Richard Ward-4
In reply to this post by Graeme Geldenhuys-6
<<Paraphrasing Graeme’s and other’s previous emails. Please refer to the posted emails and all the responses if you need to.>>

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 : 


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?


-Richard


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal