Avatar billede larsvn Nybegynder
24. oktober 2002 - 09:03 Der er 15 kommentarer og
1 løsning

Klasse-hieraki - global statisk pointer til roden ?

Jeg forsøger at bygge en objektmodel til et program, dvs. et klasse-hieraki. Roden i dette hieraki er klassen "Application". Jeg anvender VB6 til dette.

Det er nødvendigt at klasserne selv kan referere til andre klasser i hierakiet, ikke nødvendigvis med sig selv som udgangspunkt. Det vil kunne løses med en statisk pointer til rodklassen, men det kan jeg ikke få til at virke.

Jeg har forsøgt at tilføje et modul til projektet med følgende erklæring:
    Public g_Application As Application
og så initiere denne variabel i Class Application's Class_Initialize()-rutine.

Men VB6 afviser denn konstruktion med en "Run-time error '91' - Object variable ... not set" når jeg tilgår denne variabel.

Hvordan får jeg lavet en global statisk pointer til min rod-klasse, som alle klasser kan tilgå ?
Avatar billede ocp Nybegynder
24. oktober 2002 - 11:00 #1
Public g_Application As New Application?
Avatar billede ocp Nybegynder
24. oktober 2002 - 11:03 #2
Nåh nej... det kan du da ikke. Klassen kan ikke instantiere sig selv - det vil jo også medføre en ny Initialize-event... og en ny og en ny,
Avatar billede larsvn Nybegynder
24. oktober 2002 - 11:41 #3
Ja, det er meningen at klasserne blot skal registreres, og at rodklassen oprettes vha. brugerens program med CreateObject, hvorefter den opretter resten af hierakiet.
Avatar billede ocp Nybegynder
24. oktober 2002 - 11:45 #4
Fungerer dette ikke?

public Obj1 as new object1
public Obj2 as new object2
public Obj3 as new object3
Avatar billede larsvn Nybegynder
24. oktober 2002 - 13:16 #5
Måske, men det er jo ikke det jeg ønsker.

Application-objektet, som er roden af hierakiet, skal jo skabes i et eksternt program (f.eks. vha. CreateObject i VB). Det er et klassebibliotek jeg laver.

Oprettelsen af hierakiet efter denne bruger-initiering går fint, men jeg kan ikke finde ud af at gemme referencen til dette (ene) Application-objekt, så alle klasser kan anvende denne variabel til at referere til alle andre klasser (via diverse properties og metoder på Application).

Jeg kan godt være mere specifik i hvad det skal bruges til, men så tror jeg detaljerne vil overskygge essensen af problemet.
Avatar billede ocp Nybegynder
24. oktober 2002 - 13:19 #6
Jeg er bange for at jeg ikke kan hjælpe dig så.
Avatar billede larsvn Nybegynder
24. oktober 2002 - 13:58 #7
Du skal have tak for forsøget ocp.
Jeg er naturligvis også interesseret i, hvis en person autoritativt kan sige at det jeg forsøger er umuligt, og som kan anvise en brugbar alternativ metode til at opnå samme resultat.
Avatar billede kennethrisum Nybegynder
25. oktober 2002 - 23:22 #8
Hvis jeg forstår dig rigtigt, så vil du have en instance af din class som svarer til den instance som client programmet har oprettet. Som f.eks. i subclassing. Du kan finde en pointer til dig selv via ObjPtr(Me) i class'en. derefter skal du bruge api'et RtlMoveMemory (CopyMemory i API-Viewer) til at 'flytte' referencen til din lokale variabel af Class'en selv. ObjPtr(Me) har altid en længde på 4 bytes, hvilket svarer til længden af pointeren. Så i pseudo kode:

1) opret variabel af Application
2) find ObjPtr(Me)
3) flyt memory pointeren fra 2) til 1)

Håber det er det svar du leder efter? Hvis ikke tror jeg ikke jeg er helt sikker på at jeg forstår spørgsmålet.
Avatar billede larsvn Nybegynder
25. oktober 2002 - 23:45 #9
Jeg er ikke helt sikker på at det er det jeg leder efter. Jeg har som sagt opbygget et klassebibliotek (hieraki), med rodobjektet som top/indgang.

1. Brugerens program opretter "blot" mit rodobjekt vha. CreateObject("myClassLib.Application")
2. I rodobjektets Class_Initialize() opbygger jeg resten af objektmodellen, som hægtes lodret sammen, dvs. parent-child og med collections passende steder.
3. De enkelte klasseinstanser skal kunne finde andre klasseinstanser (overalt i modellen), og det er her pointeren til rodobjektet kommer ind. Med en sådan pointer kan klasserne søge sig frem i hierakiet (ligesom brugerens program selv kan).

Jeg er altså ikke interesseret i at dublere eller erstatte rodobjektet. Er det ikke det dit svar omhandler ?

Det skal bruges til at realisere en fuld (delvis read-only) objektmodel til et program der ingen har i forvejen. Og jeg har derfor ofte brug for at "refreshe" hele objektmodellen (slet + genopbyg), med rodobjektet som eneste undtagelse. Rodobjektet er dermed det eneste faste holdepunkt.
Avatar billede kennethrisum Nybegynder
27. oktober 2002 - 08:53 #10
Det mit svar kan gøre er, at du kan have reference til klassen selv (rod klassen) i f.eks. et modul. Det kræver at dit klasse hierarki ligger i ét projekt. Du kan så erklære en Public variabel i modulet
Public g_Application As Application, i class_initialize() bruger du så :

Set f_Apllication = Me

Så kan alle klasser i hierarkiet tage fat i rod objektet, igennem modulet.
Avatar billede larsvn Nybegynder
27. oktober 2002 - 11:22 #11
Det er jo sådan set det jeg har forsøgt (se i toppen).

Fra modulet:
Public g_objMIPro As Object
Public g_Application As Application

Fra klassens kode:
Private Sub Class_Initialize()
    Set g_objMIPro = GetObject(, "MapInfo.Application")
    If g_objMIPro Is Nothing Then
        Set g_objMIPro = CreateObject("MapInfo.Application")
    End If
    If g_objMIPro Is Nothing Then
        Exit Sub
    End If
   
    Set g_Application = Me
   
    strLastWorkspace = ""
   
    'build/initialize object model
    Refresh
End Sub

Og det virker tilsyneladende ikke. Når jeg tilgår g_Application fra en anden klasseinstans (dvs. under Refresh) får jeg den fejlmeddelelse jeg beskrev i problemoplægget.
Avatar billede kennethrisum Nybegynder
28. oktober 2002 - 08:43 #12
Hvordan instantierer du din rod-class fra klient programmet:

Dim obj As Application
Set obj = new Application

eller

Dim obj As New Application.

Det er den første du skal bruge. Denne skal du i øvrigt bruge hver gang du instantierer en klasse i dit projektet. Ellers risikerer du, at Class_Initialize() i rod klassen ikke er 'kørt' når du tilgår et af under objekterne.
Avatar billede larsvn Nybegynder
28. oktober 2002 - 13:32 #13
Jeg instantierer jo netop ikke selv Application-objektet, det gør brugeren i hans program (i VB vha. CreateObject).

Internt i klassebiblioteket oprettes de øvrige klasseinstanser med "set x = new Y" (via Refresh-metoden).
Avatar billede kennethrisum Nybegynder
28. oktober 2002 - 16:23 #14
Bliver Class_Initialize kørt?
Avatar billede larsvn Nybegynder
29. oktober 2002 - 11:13 #15
Please stand by while author checks his code ... ;-)
Avatar billede larsvn Nybegynder
17. november 2002 - 19:59 #16
Hej Kenneth,
Undskyld fordi det tog så lang tid. Jeg skulle lige starte på et nyt job, samt starte mit eget konsulentfirma, og det tog en masse tid.

Det er altid svært at indrømme brølere, men det gør jeg altså. Efter nøje gennemgang af koden, med dine kommentarer in mente, så må jeg konstarere at fejlen faktisk slet ikke ligger hvor jeg troede, men et andet sted.

Du får naturligvis pointene, men jeg brygger snarest et nyt spørgsmål sammen (som jeg håber løser mit problem), og jeg håber meget du også vil lægge billet ind dér :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester