Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Visual Basic > VB 6 Visual Basic 6 > VB How-To
|
VB How-To Ask your "How do I do this with VB?" questions in this forum.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the VB How-To section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old February 10th, 2004, 08:29 AM
Authorized User
 
Join Date: Jan 2004
Posts: 60
Thanks: 0
Thanked 0 Times in 0 Posts
Default Passing a class by reference

Hi,

How do I pass an instance of a class to another class?

The reason I need to do this is that I am programming an ActiveX DLL for use in a spreadsheet. The main class (class A in the following example) is instantiated by a call from the spreadsheet. The main class contains another class (class B in the following example).

Therefore, within my VB code, I do not have a handle on the instance of class A. This is a problem, because class B needs to communicate with class A. So - I am trying to pass the class A instance by reference when I instantiate class B. Actually, what I need is (in effect) a pointer (within classB) that points to classA.

In effect...

In classA:
----------

Private B as classB

Public Sub init()

    Set B = New classB

    Call B.init(Me)

End Sub

In classB:
----------

Private parentClass as classA

Public Sub init(ByRef pc As classA)

    parentClass = pc

End Sub

However, the above does not work - it throws an error.

Is my approach all wrong? Or - can I make a slight adjustment to make this work OK?

Hope you can help.

Thanks.

James

//##

 
Old February 10th, 2004, 11:46 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 101
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to jlick
Default

This looks fine to me. It would help to know what the error is, and when it occurs.

I am assuming that classA & classB are both in the same DLL. This is important, because you don't want circular references between DLLs.

John R Lick
JohnRLick@hotmail.com
 
Old February 10th, 2004, 11:52 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 2,189
Thanks: 5
Thanked 59 Times in 57 Posts
Send a message via MSN to gbianchi
Default

hi there..

you miss a set in

SET parentclass = pc

that should work..

HTH...

Gonzalo Bianchi
 
Old February 10th, 2004, 11:54 AM
Friend of Wrox
 
Join Date: Jul 2003
Posts: 683
Thanks: 0
Thanked 1 Time in 1 Post
Default

Hi James,

I think this line...

parentClass = pc

Should be...

Set parentClass = pc

HTH,

Chris


 
Old February 10th, 2004, 12:05 PM
Authorized User
 
Join Date: Jan 2004
Posts: 60
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Lovely boys! Thanks!

"Set" has solved it!

Sorry for the basic error... I am a bit new to VB.

Many many thanks for helping.

James

P.S. Another basic question: Am I right in thinking that parentClass is now effectively a "pointer" to the instance of Class A? That is, if I now change the values of variables in the instance of Class A, then parentClass can be used by the instance of Class B to access those new values?



 
Old February 10th, 2004, 12:12 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 2,189
Thanks: 5
Thanked 59 Times in 57 Posts
Send a message via MSN to gbianchi
Default

yes.. you are rigth..

but be carefull about circular references...

you have rigth now two pointers two A.. so if you set the main one to nothing..

A will not unload, and b will be alive too, and you cannot reach any of them..

to unload a first you have to set to nothing the A inside B..

the kill B.. and then you can kill A

HTH...

Gonzalo Bianchi
 
Old February 10th, 2004, 12:33 PM
Authorized User
 
Join Date: Jan 2004
Posts: 60
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hmmmm....ok

But parentClass is not a COPY of the instance, is it? It's just a pointer to the instance, right?

If I set the instance of classA to nothing ("destroy" it), then parentClass becomes just a pointer to nothing.

Is that right?

 
Old February 10th, 2004, 01:51 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 2,189
Thanks: 5
Thanked 59 Times in 57 Posts
Send a message via MSN to gbianchi
Default

well.. unless I made a mistake (somebody correct me if i am) destroying an instance of a pointer dont destroy the class, because it have another pointer to it..

try this.. put a msgbox in the terminate of the class..

destroy the first pointer.. and you will see that the msgbox doesnt appear.. so the class is still alive, but you dont have any pointer to it... :(

HTH...


Gonzalo Bianchi
 
Old February 10th, 2004, 04:43 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 627
Thanks: 0
Thanked 0 Times in 0 Posts
Default

No, setting a VB object (or class) to Nothing just decreases the reference count of that object, and the object is destroyed only when the reference count goes to zero. In your case, when you pass your class with the Set statement, the reference count was increased by one. This is the beauty of COM (any VB object is in reality a COM object): classes are destroyed only when no one is use them anymore, so you do not have to worry cleaning up the memory and no need for garbage collector.

But is has a caveat: when you create a circular reference (class A create class B and keeps a pointer to B, and class B keeps a pointer to A) set class A to nothing DOES NOT destroy it, because another class (in this case B) is still using it.

The best way to fix circular references: do not use them.... been there, done it. BTW the garbage collector has been reinstated in .NET

Marco



Quote:
quote:Originally posted by James Diamond
 Hmmmm....ok

But parentClass is not a COPY of the instance, is it? It's just a pointer to the instance, right?

If I set the instance of classA to nothing ("destroy" it), then parentClass becomes just a pointer to nothing.

Is that right?

 
Old February 11th, 2004, 12:46 PM
Authorized User
 
Join Date: Jan 2004
Posts: 60
Thanks: 0
Thanked 0 Times in 0 Posts
Default

OK - thanks.

It seems to me that I can't avoid this circular reference in this case. I don't know how else to give class B a means of talking to class A. That is because class A is instantiated by a call from my spreadsheet. (class A and class B are in the DLL I am writing in VB6, that is used by the spreadsheet).

If there is another way, please let me know.

A related question... My spreadsheet does this when a command button is clicked:

Set theEngine = New classEngine

The instance of classEngine then does some stuff (including creating some instances of other classes it contains). It then passes results back to the spreadsheet.

When the command button is clicked again, this is repeated. So I would end up with loads of class instances created after many clicks of the button.

I guess this is not very good, as it means loads of redundant objects floating around. Is that right?

Please can you help me understand object-management in this respect, so that I don't go down the wrong route.

Thanks.

James

P.S. Regarding cleanup, when the spreadsheet is closed, am I right in presuming that that destroys all the class instances that I have created via the DLL? i.e. I get an automatic cleanup?





Similar Threads
Thread Thread Starter Forum Replies Last Post
Using class reference getting error rojiin ASP.NET 2.0 Basics 2 July 6th, 2007 01:53 PM
Reference Cache or Application from a class pauliehaha ASP.NET 2.0 Professional 1 April 17th, 2007 09:51 AM
Passing by reference quiksilverhg Excel VBA 5 November 21st, 2005 03:49 AM
Reference a class within ocx shahpragnesh_p Pro VB Databases 1 August 28th, 2003 08:31 AM
Passing by reference jacob ASP.NET 1.0 and 1.1 Basics 1 July 12th, 2003 05:07 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.