User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Pascal and Delphi section within the Software Development category of DaniWeb, a massive community of 374,167 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,334 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Pascal and Delphi advertiser:
Views: 1512 | Replies: 5
Reply
Join Date: Oct 2007
Posts: 34
Reputation: adrive is an unknown quantity at this point 
Rep Power: 1
Solved Threads: 0
adrive adrive is offline Offline
Light Poster

delphi object casting

  #1  
Dec 12th, 2007
i'm not sure if i'm getting this right, but i still remember java allowing me to cast an object to another type as long as their ancestors are the same?

I can't seem to do this in delphi, the compiler doesn't seem to understand the methods and attributes of each object even after I've casted them. What's wrong?

I'm trying to figure out how to stick two database query objects under the same name as illustrated :

qry : TObject;


if(callType = 'A') then
begin

//casting qry as a TOraQuery object :

qry := TOraQuery.Create(nil);
qry := commonObj.GetConnection('DATABASE_A');

qry.SQL.Add('DELETE FROM TEST1');
qry.ExecSQL;
qry.SQL.Clear;
end;

if(callType = 'B') then
begin

//casting qry as a TADOConnection object :

qry := TADOConnection.Create(nil);
qry := commonObj.GetConnection('DATABASE_B');

qry.SQL.Add('DELETE FROM TEST2');
qry.ExecSQL;
qry.SQL.Clear;
end;
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Sep 2007
Posts: 61
Reputation: ExplainThat is an unknown quantity at this point 
Rep Power: 1
Solved Threads: 6
ExplainThat ExplainThat is offline Offline
Junior Poster in Training

Re: delphi object casting

  #2  
Dec 14th, 2007
ADrive, it may be possible that you have not fully understood just how Delphi typecasts work. First thing first - though not wrong, it does strike me as odd that you should assign the object you want to typecast as a TObject - I would have used a raw pointer. Secondly, what you have done is not really a typecast at all. I provide a few examples below which might point you in the right direction.
  • Imagine that we have a TMaskEdit component on a form
  • You want to use the OnClick event handler for this component
    []]The empty template Delphi gives you will go like this

procedure TMyForm.MaskEdit1Click(Sender:TObject)
begin
   with TMaskEdit(Sender) do
   begin
       MaxLength:=32;
       Text:='Top Secret';
   end;
end;

Here we done the typecast as TMaskEdit(Sender). The with block ensures that the properties MaxLength and Text of your TMaskEdit control can be correctly accessed.

Here is another way to do the same thing

procedure TMyForm.MaskEdit1Click(Sender:TObject)
var AEdit:TMaskEdit absolute Sender;
begin
   with AEdit do
   begin
       MaxLength:=32;
       Text:='Top Secret';
   end;
end;

Here we dispense with the explicit typecast. Instead we declare a local TMaskEdit variable which sits at the same memory location as the Sender parameter. Note that you have not created a new TMaskEdit object - you are simply referencing the Sender object in a different way.

Now look at something closer to your own example

procedure TMyForm.MyADOCode;
var qry:TObject;
//like I said, I would rather do var qry:Pointer;
begin
   qry:=TOraQuery.Create(nil);
   with TOraQuery(qry) do
   begin
       SQL.Add('Delete from Test 2');
       ExecSQL;
       Clear;
   end;
end;

I am not entirely clear just what you are trying to do but I hope this helps you make sense of Delphi typecasts.

There are a number of miscellaneous points to emphasize
  • Code such as this should normally go inside a try...finally block and you must ensure that the object you created is freed up once you are done.
  • You can reference multiple objects in a with block. For instance

procedure TMyForm.WithExample;
var AllNames:String;
      qry:TOraQuery;
      ANames:TStringList;
begin
   with qry,ANames do
   begin
       SQL.Add('Delete from Test 2');//references the SQL property of qry
       AllNames:=Text;//references the Text property of ANames  
       ExecSQL;//calls the ExecSQL method of qry
       Clear;//clears qry
   end;
end;


When you have such code Delphi scoping rules come into play. The first three lines of code raise no issues. The fourth one, Clear, is rather more complicated. Remember that both the TOraQuery and the TStringList classes have a Clear method. So which of the two objects will get cleared? Given the order in which we have specified them in the with block it will be qry. This can lead to very hard to trace bugs so be careful when writing such statements!
Reply With Quote  
Join Date: Oct 2007
Posts: 34
Reputation: adrive is an unknown quantity at this point 
Rep Power: 1
Solved Threads: 0
adrive adrive is offline Offline
Light Poster

Re: delphi object casting

  #3  
Dec 19th, 2007
thanks explainthat, its really very informative.

but what i really wanted to do was to be able to use one variable to represent different types of database connection, one was TADOConnection, another TOraQuery, both sharing same qry variable.

this is because they both have some similiar method names and thus i could probably reduce my code lines by eliminating the need to do alot of conditional statements and switch between different variable types.
Reply With Quote  
Join Date: Sep 2007
Posts: 61
Reputation: ExplainThat is an unknown quantity at this point 
Rep Power: 1
Solved Threads: 6
ExplainThat ExplainThat is offline Offline
Junior Poster in Training

Re: delphi object casting

  #4  
Dec 19th, 2007
Originally Posted by adrive View Post
thanks explainthat, its really very informative.

but what i really wanted to do was to be able to use one variable to represent different types of database connection, one was TADOConnection, another TOraQuery, both sharing same qry variable.

this is because they both have some similiar method names and thus i could probably reduce my code lines by eliminating the need to do alot of conditional statements and switch between different variable types.


Like I explained, you should be able to do that with a combination of a typecast and a with statement as I have done.

var qry:Pointer;//or TObject if you want it that way
qry:=TADOConnection.Create(nil);
with TADOConnection(qry) do
begin
   //full access to TADOConnection methods and properties here
end;

with TOraQuery(qry) do
begin
   //ditto
end;

Post your actual code - not working if that happens to be the case - if this does not make complete sense and I'll correct it for you.
Reply With Quote  
Join Date: Dec 2007
Location: Zagreb, Croatia
Posts: 4
Reputation: Smola is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
Smola's Avatar
Smola Smola is offline Offline
Newbie Poster

Re: delphi object casting

  #5  
Dec 26th, 2007
Originally Posted by adrive View Post
i'm not sure if i'm getting this right, but i still remember java allowing me to cast an object to another type as long as their ancestors are the same?


Actually you can _cast_ any object to any class, but you cannot _assign_ an ancestor-object to a variable of its descendant class.

Therefore you cannot assign TStrings to the TStringList, only vice-versa.

Originally Posted by adrive View Post
I can't seem to do this in delphi, the compiler doesn't seem to understand the methods and attributes of each object even after I've casted them. What's wrong?

I cannot see a single casting in your code. Casting looks like something this:

myQuery := TQuery( myOraQuery );


Originally Posted by adrive View Post
I'm trying to figure out how to stick two database query objects under the same name as illustrated :

I think TOraQuery and TADOConnection don't have the same ancestor that would have properties like ExecSQL and SQL. So you must use the approach suggested by ExplainThat.


Originally Posted by adrive View Post
//casting qry as a TOraQuery object :
qry := TOraQuery.Create(nil);
qry := commonObj.GetConnection('DATABASE_A');

This is not casting. This is merely creating an instance of the TOraQuery and than losing that reference immedietely afterwards (which is a memory leak).

Originally Posted by adrive View Post
but what i really wanted to do was to be able to use one variable to represent different types of database connection, one was TADOConnection, another TOraQuery, both sharing same qry variable.

this is because they both have some similiar method names and thus i could probably reduce my code lines by eliminating the need to do alot of conditional statements and switch between different variable types.


Unfortunately, those similar method names cannot be exploited, you'll have to duplicate your code, or use an alternative connection component.

Hope I've shed some light.
Doom on, soldier.
Reply With Quote  
Join Date: Oct 2007
Posts: 34
Reputation: adrive is an unknown quantity at this point 
Rep Power: 1
Solved Threads: 0
adrive adrive is offline Offline
Light Poster

Re: delphi object casting

  #6  
Jan 7th, 2008
thanks guys, you were really helpful!
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

DaniWeb Pascal and Delphi Marketplace
Thread Tools Display Modes

Other Threads in the Pascal and Delphi Forum

All times are GMT -4. The time now is 4:15 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC