Re: OO problem: How to create a duplicate of a derived class with only a base variable ?

From: Skybuck Flying (nospam_at_hotmail.com)
Date: 11/19/04


Date: Fri, 19 Nov 2004 10:20:51 +0100

Well maybe creating objects via

Self.Create is logical ?

Since the delphi help shows that Tobject has a create method/constructor.

And the old style of creating objects is allowed

for example

type
    Tbla = object
    end;

var
    A : Tbla;
begin
    A.Create; // this is absolutely valid ! :)
end;

Since Self is an "object" and not "a class"

Self.Create would be valid ?????

That could explain it.

That would mean that a "class" *is not 100% the same* as an "object" !

Suppose all this is true and it really works without being a class
function.. then can you give any reason why it should still be a class
function ???????

Since it doesn't seem needed for the purpose it was ment for

(the duplication function )

Then it doesn't need to be a class function ?!?! :)

Woowww wacky.

Hehe... it was me by the way who thought it had to be a class function...

I was simply "mimicing" your (Rob's) BaseClassType class function :)

And the best thing of all is... if it doesn't have to be a class function...
then it can probably be shortened to

function Tbase.Duplicate : Tbase;
begin
 result := Self.Create;

 // no more need for the source parameter :)
 result.Assign( Self );
end;

Bye,
  Skybuck.

"Skybuck Flying" <nospam@hotmail.com> wrote in message news:...
> Hey,
>
> That's weird...
>
> I was wondering what class functions really are... etc and why they are
> needed...
>
> Then I begane to wonder if it was really needed.. and surprise surprise...
> it isn't really needed in the code example... it compiles perfectly
without
> it which is kinda funny...
>
> I am not sure if it would or would not lead to bugs...
>
> I am not sure if it is valid or invalid code style...
>
> Look at this:
>
> class function Duplicate( Source : Tbase ) : Tbase;
>
> now simply comment out the class thing
>
> {class} function Duplicate( Source : Tbase ) : Tbase;
>
> comment it out for the implementation as well and then simply compile it.
>
> {class} function Tbase.Duplicate( Source : Tbase ) : Tbase;
> begin
> result := Self.Create; // I WONDER is it allowed to create objects like
> this ???????????
>
> // normally it *does* compile but it *does not* work
>
> // but this time it seems to *work*.. or maybe that's just an
*illusion*
> ?
> // Self is now a class reference so it can be used to create a new
> instance.
>
> // The question is.. can Self also be used to "get" the current instance
?
>
> // if not then we might need the Source parameter...
>
> // we will assume that the base class and the derived classess all have
> an Assign method
> // the assign method copies stuff to itself so..
>
> // ***
> // if somehow the duplicate function could figure out a way to get the
> class instance
> // etc then this source parameter might not be needed !
> // and Result.Assign( Self.Instance ) could be used ;)
> // ***
>
> Result.Assign( Source );
>
> end;
>
>
> Bye,
> Skybuck.
>
>
> "Skybuck Flying" <nospam@hotmail.com> wrote in message news:...
> > Ok,
> >
> > Maybe now it's possible to somehow write a class duplicate function
which
> > would only be needed to write once for the base class.
> >
> > Yup...
> >
> > I just wrote it and tested it a bit... ;)
> >
> > The only thing that might be improved is the "Source : Tbase"
parameter...
> >
> > Maybe it's somehow possible to get the "current instance" for a
> > class-reference variable ???
> >
> > See *** ;)
> >
> >
> > program Project1;
> >
> > {$APPTYPE CONSOLE}
> >
> > uses
> > SysUtils;
> >
> > type
> > TbaseClass = class of Tbase;
> > Tbase = class
> > private
> >
> > public
> >
> > // function MyClassType : TbaseClass; virtual; // not needed any more
> > thanks to class function
> >
> > class function MyClassType2 : TbaseClass;
> >
> > class function Duplicate( Source : Tbase ) : Tbase;
> >
> > procedure Assign( Source : Tbase ); virtual; abstract;
> >
> > end;
> >
> > Tderived1 = class(Tbase)
> > private
> > public
> > a,b,c : string;
> >
> > // function MyClassType : TbaseClass; override; // not needed any more
> > thanks to class function in base class
> >
> > procedure Assign( Source : Tbase ); override; // needed so that this
one
> > is called from base references.
> >
> > end;
> >
> > Tderived2 = class(Tbase)
> > private
> > public
> > i : integer;
> >
> > // function MyClassType : TbaseClass; override; // not needed any more
> > thanks to class function in base class
> >
> > procedure Assign( Source : Tbase ); override; // needed so that this
one
> > is called from base references.
> >
> > procedure Derived2Only;
> > end;
> >
> > class function Tbase.MyClassType2 : TbaseClass;
> > begin
> > result := Self;
> > end;
> >
> > {
> > procedure Tbase.Assign( Source : Tbase );
> > begin
> > // nothing to copy. we could make it abstract but why run the risk of
> > errors at runtime ;)
> > // oh well otherway it will cause bugs anyway.
> >
> > // oh i see.. abstract does have a usefull function and that is to make
> it
> > "required"/"mandotory"
> > // to have this in all derived classess... wel in that case let's make
it
> > abstract :)
> > // otherwise it wont work anyway :)
> > end;
> > }
> >
> > class function Tbase.Duplicate( Source : Tbase ) : Tbase;
> > begin
> > result := Self.Create;
> >
> > // Self is now a class reference so it can be used to create a new
> > instance.
> >
> > // The question is.. can Self also be used to "get" the current
instance
> ?
> >
> > // if not then we might need the Source parameter...
> >
> > // we will assume that the base class and the derived classess all
have
> > an Assign method
> > // the assign method copies stuff to itself so..
> >
> > // ***
> > // if somehow the duplicate function could figure out a way to get the
> > class instance
> > // etc then this source parameter might not be needed !
> > // and Result.Assign( Self.Instance ) could be used ;)
> > // ***
> >
> > Result.Assign( Source );
> >
> >
> > end;
> >
> > procedure Tderived1.Assign( Source : Tbase );
> > begin
> > {
> > a := Source.a; // oops won't compile
> > b := Source.b;
> > c := Source.c;
> > }
> > // I wish I didn't have to typecast here... :)
> > // oh well I going to use something else instead
> > // I am going to use the As... I dont really see what's different about
> it
> > // or why that it is usefull.. is just another form of typcasting to
> me...
> > // but it has a little adventage... i can just write (Source as and
then
> > think about it :) )
> > // so it postpones thinking about it a little bit hehhe <- that's lazy
:)
> > // but writing As is also automatic. I rather right as so I have to go
> back
> > and correct it, darn.
> > a := (Source as Tderived1).a;
> > b := (Source as Tderived1).b;
> > c := (Source as Tderived1).c;
> > end;
> >
> > procedure Tderived2.Assign( Source : Tbase );
> > begin
> > // i := Source.i;
> >
> > i := (Source as Tderived2).i;
> > end;
> >
> >
> >
> > // not needed any more thanks to class function in base class
> > {
> > function Tbase.MyClassType : TbaseClass;
> > begin
> > result := Tbase;
> > end;
> >
> > function Tderived1.MyClassType : TbaseClass;
> > begin
> > result := Tderived1;
> > end;
> >
> > function Tderived2.MyClassType : TbaseClass;
> > begin
> > result := Tderived2;
> > end;
> > }
> >
> > procedure Tderived2.Derived2Only;
> > begin
> > writeln('This method only exists in Derived 2');
> > end;
> >
> >
> >
> > var
> > Something : Tbase;
> >
> > Something1 : Tbase;
> > Something2 : Tbase;
> >
> > begin
> >
> > Something := Tderived1.Create;
> >
> > (*
> > if Something.MyClassType = Tderived1 then
> > begin
> > writeln('yup');
> >
> > // what if I call a non existent method like Derived2Only.
> >
> > // oh I see... Class of Types only have a limited number of methods
> > // so it can't be called here... not like this ;)
> >
> > // only the limited methods like the constructor can be called here
> > // destructor exists as well..
> > // these methods are actually part of Tobject :) ;)
> >
> > // nope can't be used to typecast ? hehe
> > // Something.MyClassType( Something );
> >
> > // wow this is wierd ?!
> >
> > // something is actually a Tderived1
> > // but with this trick the method of Tderived2 can still be called ?
> > // wow is this valid/legal/robust ? or could it lead to access
> violations
> > ?
> > // I guess as long as Derived2Only does not attempt to access any
fields
> > // it would possible work... or maybe if it is the same size
> > // it could actually still work with the data of a derived 1 instance
?!
> > // wow... that's like "method type" casting on object data :)
> > TDerived2( Something.MyClassType ).Derived2Only;
> >
> > end;
> > *)
> >
> > if Something is Tderived1 then
> > begin
> > writeln('something is a Tderived1');
> > end;
> >
> > if Something.ClassType = Tderived1 then
> > begin
> > writeln('something is a Tderived1');
> > end;
> >
> >
> > if Something.MyClassType2 = Tderived1 then
> > begin
> > writeln('excellent');
> > end;
> >
> > // let's put our duplicate function to the test
> >
> > Something1 := Tderived1.Create;
> > Tderived1(Something1).a := 'Hello world';
> > Tderived1(Something1).b := 'It''s a nice day today';
> > Tderived1(Something1).c := 'Now stop writing :)';
> >
> > // ***
> > // if somehow the duplicate function could figure out a way to get the
> > class instance
> > // etc then this source parameter might not be needed !
> > // ***
> >
> > Something2 := Something1.Duplicate( Something1 );
> >
> > // yup duplication successfull
> > writeln( Tderived1(Something2).a );
> > writeln( Tderived1(Something2).b );
> > writeln( Tderived1(Something2).c );
> >
> >
> > readln;
> >
> > end.
> >
> > Bye,
> > Skybuck.
> >
> >
>
>



Relevant Pages

  • Re: C++ design question
    ... >> does not initialize the specific base class instance created as a part ... >> of creating an instance of this derived class if that was the intent. ... >> class instance part if that is the intent. ...
    (comp.object)
  • Re: "Hiding" an inherited property?
    ... > class invisible to the programmer? ... For it to be possible to treat any inherited class instance as though it ... were a base class instance, the inherited class must have all of the members ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Petition again MS
    ... Private class variables are not private to the class instance. ... Private _aClass As New AClass ...
    (microsoft.public.vb.general.discussion)
  • Re: Ruby Basics / define met;hod
    ... "Inside a class body /self/ is the class instance being defined right ... Private methods can normally be only invoked without an explicit receiver, ... Then I went on to explain that /private/ in Ruby is rather weak because you can invoke private methods on any instance simply by going through /send/. ...
    (comp.lang.ruby)
  • Re: Petition again MS
    ... And a lot of that is not syntax changes ... And a lot of it is incorrect. ... Private class variables are not private to the class instance. ...
    (microsoft.public.vb.general.discussion)