Forum > Suggestions

Really VOID Class

<< < (2/6) > >>

Awkward:
dual model is bad idea? say that to advanced record creators! THAT was a bad idea, to make records with bonuses if we has objects already. And your Void classes will be little more than unuseful coz direct descendants will be not compatible with TObject descendants

damieiro:

--- Quote ---dual model is bad idea? say that to advanced record creators! THAT was a bad idea, to make records with bonuses if we has objects already.
--- End quote ---

Dual model without full support *IS* bad idea. Yes. Better a full supported one.
And a stack object isn't a heap class. Well it is with manual management like any type. But well, a void class could be (with some tweaking) be the same as a object and interchangeable in pointers...

 
--- Quote ---And your Void classes will be little more than unuseful coz direct descendants will be not compatible with TObject descendants
--- End quote ---
Which is intended. Do you need a Tobject descendand?. Declare a TMyClass=class(TObject).
Do you need a Void class descendant? Declare TMyClass=class(Void) or TMyClass=voidclass because TMyClass=class, it's taken as class(TObject).. so we can't use it.

But i do not need that over defined and oversized TObject. So give me the raw object to interact with this.

When you declare a Tcar=class... Do you use...
...DefaultHandler()?
...InstanceSize?
...GetInterface()?.
for example.
would like that your new class should not answer to .create or .destroy? (not fail safe)

This TObject in all his glory


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---   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;          { the virtual procedures must be in THAT order }          destructor Destroy;virtual;          class function newinstance : tobject;virtual;          procedure FreeInstance;virtual;          function SafeCallException(exceptobject : tobject;            exceptaddr : codepointer) : HResult;virtual;          procedure DefaultHandler(var message);virtual;           procedure Free;          class function InitInstance(instance : pointer) : tobject; {$ifdef SYSTEMINLINE} inline; {$endif}          procedure CleanupInstance;          class function ClassType : tclass;{$ifdef SYSTEMINLINE}inline;{$endif}          class function ClassInfo : pointer;          class function ClassName : shortstring;          class function ClassNameIs(const name : string) : boolean;          class function ClassParent : tclass;{$ifdef SYSTEMINLINE}inline;{$endif}          class function InstanceSize : SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}          class function InheritsFrom(aclass : tclass) : boolean;          class function StringMessageTable : pstringmessagetable;           class function MethodAddress(const name : shortstring) : codepointer;          class function MethodName(address : codepointer) : shortstring;          function FieldAddress(const name : shortstring) : pointer;           { new since Delphi 4 }          procedure AfterConstruction;virtual;          procedure BeforeDestruction;virtual;           { new for gtk, default handler for text based messages }          procedure DefaultHandlerStr(var message);virtual;           { message handling routines }          procedure Dispatch(var message);virtual;          procedure DispatchStr(var message);virtual;           { interface functions }          function GetInterface(const iid : tguid; out obj) : boolean;          function GetInterface(const iidstr : shortstring;out obj) : boolean;          function GetInterfaceByStr(const iidstr : shortstring; out obj) : boolean;          function GetInterfaceWeak(const iid : tguid; out obj) : boolean; // equal to GetInterface but the interface returned is not referenced          class function GetInterfaceEntry(const iid : tguid) : pinterfaceentry;          class function GetInterfaceEntryByStr(const iidstr : shortstring) : pinterfaceentry;          class function GetInterfaceTable : pinterfacetable;           { new since Delphi 2009 }          class function UnitName : {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};          class function QualifiedClassName: {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};          function Equals(Obj: TObject) : boolean;virtual;          function GetHashCode: PtrInt;virtual;          function ToString: {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};virtual;       end;                       end;

TObject is half bloated, half hacky and full oversized for nearly 99.9% of uses.
Note: this is not a dev blame. It's being as this for historical reasons, but a raw heap class is, for me, a desirable one.

PascalDragon:

--- Quote from: damieiro on September 23, 2021, 07:35:20 pm ---I think it's desirable some kind of lightweight class without all the bloat like a
TVoidClass and TObject should derive from the TVoidClass.
--- End quote ---

There is no desire to change or extend the object model. If you need something lightweight use object.


--- Quote from: damieiro on September 23, 2021, 10:08:36 pm ---TObject is half bloated, half hacky and full oversized for nearly 99.9% of uses.
--- End quote ---

First: if smartlinking is enabled (default on Windows) any non virtual methods of TObject are removed.
Second: nothing there is hacky, it's simply a type that makes use of the low level information generated by the compiler, that's why it's a core type of the RTL.
Third: It's not oversized for 99.9% of uses, because the LCL makes use of nearly all the functionality provided by TObject to provide all the functionality we know and love and LCL usage is clearly more than 0.1%.

y.ivanov:
IMHO advanced records aren't a bad idea. See https://forum.lazarus.freepascal.org/index.php/topic,46306.msg329970.html#msg329970

Such auto objects gives some advantages that C++ has by default.

damieiro:

--- Quote ---
--- Quote from: PascalDragon on September 24, 2021, 09:16:56 am ---
--- Quote from: damieiro on September 23, 2021, 07:35:20 pm ---I think it's desirable some kind of lightweight class without all the bloat like a
TVoidClass and TObject should derive from the TVoidClass.
--- End quote ---

There is no desire to change or extend the object model. If you need something lightweight use object.
--- End quote ---

--- End quote ---


It's not the same and you know it. Object won't be developed further. It has not the sugar candy syntax. It's stacked, not in heap.. Same you said that it's a bad idea being with objects because their limitations can't be offered as a similar solution. It's not the same and it hasn't the same priority. And are useless in Delphi (embarcadero deprecated them).
And it's a bad idea two types of coding (for objects) and for TObjects. Duality for same things is allways bad idea. Telling that use object instead of making a voidheap one is a straw man argument. https://en.wikipedia.org/wiki/Straw_man
This argument will be acceptable if object would hace exactly the same functionality, nor less as a heap object and being sugar-sintax in heap and fully mainteinance. Object its even an antecesor of record with methods. It's an ancient way of doing things and not a supported one. Would you advise to ANY who is starting with fpc to use objects or classes? You will answer: go for classes. So no room for : Go for objects as an advice.


--- Quote from: damieiro on September 23, 2021, 10:08:36 pm ---
--- Quote ---TObject is half bloated, half hacky and full oversized for nearly 99.9% of uses.
--- End quote ---

First: if smartlinking is enabled (default on Windows) any non virtual methods of TObject are removed.
Second: nothing there is hacky, it's simply a type that makes use of the low level information generated by the compiler, that's why it's a core type of the RTL.
Third: It's not oversized for 99.9% of uses, because the LCL makes use of nearly all the functionality provided by TObject to provide all the functionality we know and love and LCL usage is clearly more than 0.1%.

--- End quote ---

First, smartlinking only removes interface ones (below). The other are class functions that could viewed as compiler constructs and being out of class scope or in the class scope (but this is taste) -> This is RTL not a part of a class. And should be the class designer if use it or other compiler info. Give TObject as is, and let a void one to be generated as object with the same funcionality as object and fully maintained. And it's how an academic OOP should be. Why is this change problematic?. It's making the actual model to an universal, fully academic supported and fully compatible with existing code. This can have many views. One can have (by sugar sintax) define that class-RTL methods could be in all classes (like in a void class)-> example
(MyAscendant:=TFooClass.ClassParent) or as (MyAscendant:=ClassParent (TFooClass); And i could argue the later can have advantages too. could you do this with an object. NO.
But the main question is why is difficult or not viewed as neccesary a Void object which should be the academic root to start working and gives tools to do other things and not Lazarus-delphi ones? I think it's a autoimposed limitation.

Second, better not doing a smartlinking job when you don't need to smart link if better defined.


Not too much gain...
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;
          { the virtual procedures must be in THAT order }
          destructor Destroy;virtual;
          class function newinstance : tobject;virtual;
          procedure FreeInstance;virtual;
          function SafeCallException(exceptobject : tobject;
            exceptaddr : codepointer) : HResult;virtual;
          procedure DefaultHandler(var message);virtual;
 
          procedure Free;
          class function InitInstance(instance : pointer) : tobject; {$ifdef SYSTEMINLINE} inline; {$endif}
          procedure CleanupInstance;
          class function ClassType : tclass;{$ifdef SYSTEMINLINE}inline;{$endif}
          class function ClassInfo : pointer;
          class function ClassName : shortstring;
          class function ClassNameIs(const name : string) : boolean;
          class function ClassParent : tclass;{$ifdef SYSTEMINLINE}inline;{$endif}
          class function InstanceSize : SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
          class function InheritsFrom(aclass : tclass) : boolean;
          class function StringMessageTable : pstringmessagetable;
 
          class function MethodAddress(const name : shortstring) : codepointer;
          class function MethodName(address : codepointer) : shortstring;
          function FieldAddress(const name : shortstring) : pointer;
 
          { new since Delphi 4 }
          procedure AfterConstruction;virtual;
          procedure BeforeDestruction;virtual;
 
          { new for gtk, default handler for text based messages }
          procedure DefaultHandlerStr(var message);virtual;
 
          { message handling routines }
          procedure Dispatch(var message);virtual;
          procedure DispatchStr(var message);virtual;
 
          { interface functions }
          function GetInterface(const iid : tguid; out obj) : boolean;
          function GetInterface(const iidstr : shortstring;out obj) : boolean;
          function GetInterfaceByStr(const iidstr : shortstring; out obj) : boolean;
          function GetInterfaceWeak(const iid : tguid; out obj) : boolean; // equal to GetInterface but the interface returned is not referenced
          class function GetInterfaceEntry(const iid : tguid) : pinterfaceentry;
          class function GetInterfaceEntryByStr(const iidstr : shortstring) : pinterfaceentry;
          class function GetInterfaceTable : pinterfacetable;
 
          { new since Delphi 2009 }
          class function UnitName : {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};
          class function QualifiedClassName: {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};
          function Equals(Obj: TObject) : boolean;virtual;
          function GetHashCode: PtrInt;virtual;
          function ToString: {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};virtual;
       end;                     
 
end;



Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version