Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Muttonhead
Anmeldungsdatum: 26.08.2008 Beiträge: 562 Wohnort: Jüterbog
|
Verfasst am: 29.01.2014, 23:01 Titel: mehrere types durch ein "Listobjekt" verwalten |
|
|
Ich will mehrere Types durch ein sog. Listenobjekt verwalten lassen. Jedem seine eigene Liste. Theoretisch
wäre auch eine Mischliste möglich, aber das ist wohl wenig sinnvoll.
So weit scheint es auch zu funktionieren.
Jedoch ist das Hinzufügen weiterer Types sehr aufwendig, zumindest in meiner "Lösungsvariante".
Es sind immer zu viele Baustellen die angepaßt werden müssen.
Wenn jemand ne Idee hat das ganze ewas einzudampfen...
http://www.freebasic-portal.de/porticula/mehrere-udts-durch-ein-listenobjekt-verwalten-1697.html
Mutton |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 30.01.2014, 09:07 Titel: |
|
|
Ich verweise mal auf mdTypes.
Wenn du sowieso für jeden Type eine eigene Liste haben willst, dann kannst du das so definieren:
Code: |
mdListDeclare(sGUIType1)
mdListDeclare(sGUIType2)
mdListDeclare(sGUIType3)
'...
Dim as mdList(sGUIType1) type1List
Dim as mdList(sGUIType2) type2List
Dim as mdList(sGUIType3) type3List
'...
|
Dafür musst du aber die geforderten Operatoren zusätzlich implementierent (siehe Beispiel).
Als Pointer könntest du natürlich alle Types in einer Liste verwalten. Dazu könntest du dir einen zusätzlichen Type schreiben, der den Pointer und den Bezeichner des Types hinter dem Pointer speichert und es so machen.
mdTypes erlauben zwar auch Pointer direkt zu hinterlegen, also eine Liste von Pointern, aber dann hast du die Gefahr, dass du den Pointer zum falschen Type castest, wenn diese Information nicht mitgegeben wird. |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2507 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 30.01.2014, 21:41 Titel: |
|
|
Mittlerweilen auch an Objektorientierung und Polymorphismus denken und in diesem Zusammenhang die von mir unter
http://forum.qbasic.at/viewtopic.php?t=8363
gezeigten Beispiele anschauen. Vermutlich hat Dein Projekt ähnliche Strukturen, d.h. gewisse gemeinsame Methoden "verstehen" sämtliche Objekte bzw. bei Dir Listeneinträge, und gewisse sind individuell, so dass es einen Cast braucht. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Muttonhead
Anmeldungsdatum: 26.08.2008 Beiträge: 562 Wohnort: Jüterbog
|
Verfasst am: 31.01.2014, 12:22 Titel: |
|
|
@beide:
Wobei ich aber generell denke, Ich kann vererben wie und was ich will, spätestens wenn ich einen "a ptr" als "b ptr" nutzen will
ist Handarbeit angesagt.Es löst nicht alle Probleme
@MOD:
Da hab ich doch glatt ne Frage:
Code: |
#Include Once "md/util/mdList.bi"
Type MyClass
Declare Constructor ()
Declare Operator Cast() As String
As Integer myVar
End Type
'must have a default constructor or no explicit constructor at all!
Constructor MyClass ()
End Constructor
'must implement cast to string for string representation
Operator MyClass.Cast() As String
Return Str(myVar)
End Operator
'operator for comparision must exist!
Operator = (ByRef lhs As MyClass, ByRef rhs As MyClass) As Integer
Return lhs.myVar = rhs.myVar
End Operator
mdListDeclare(MyClass)
Dim As mdList(MyClass) list
Dim As MyClass foo
foo.myVar = 0 : list.add(foo)
foo.myVar = 1 : list.add(foo)
foo.myVar = 2 : list.add(foo)
foo.myVar = 3 : list.add(foo)
foo.myVar = 0 : list.add(foo)
Print "Output 1:"
For i As Integer = 0 To list.size() - 1
Print list.get(i).myVar
Next
Print
Print "Output 2:"
Dim As MyClass element
ForEach(MyClass, element In list)
Print element.myVar
NextEach
Print
Print "Output 3:"
Dim As mdIterator(MyClass) iterator = list.iterator()
While iterator.hasNext()
Print iterator.nex().myVar
Wend
Print
Sleep
|
Was das so im Hintergrund passiert, kann ich erstmal nicht nachvollziehen, hab das Schlüsselwort EXTEND gesehen,
das hat mir dann erstmal genügt. *g*
Um mein Type in mdList zu benutzen, muß es also auch bestimmte Bedingungen erfüllen, ok soll dann so sein.
wenn ich das richtig verstehe erzeugst du mit
Code: |
mdListDeclare(MyClass)
Dim As mdList(MyClass) list
|
eine Liste in der mein Type iwie "aufgeht".
Code: |
Dim As MyClass foo
foo.myVar = 0 : list.add(foo)
foo.myVar = 1 : list.add(foo)
foo.myVar = 2 : list.add(foo)
foo.myVar = 3 : list.add(foo)
foo.myVar = 0 : list.add(foo)
|
mit foo dimensionierst du ein "Musterobjekt", dessen Kopie "geadded" wird.
Der Zugriff auf das Listenelement irgendwann später, scheint ja dann "nur" noch via einem Index zu gehen.
Nur wie komme ich an diesen heran? nur über .size()-1 direkt nach dem .add() aufgerufen?
.add() ist zwar ne Funktion, berichtet aber warscheinlich nur intern vom Erfolg des Hinzufügens.
Mutton |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 31.01.2014, 13:40 Titel: |
|
|
Im Hintergrund wird ein gigantisches Macro zu einer komplexen hierarchischen Vererbungsstruktur aufgelöst.
Der Vorteil ist, dass die Listen zueinander kompatibel sind.
Dein Type muss bestimmte Eigenschaften erfüllen, damit die Liste bestimmte Funktionen darauf ausüben kann.
Der leere Constructor muss vorhanden sein, damit die Liste neue Elemente erstellen kann, der Cast to String Operator muss für die Umwandlung in die String-Repräsentation vorhanden sein und ein externer Vergleichsoperator "=" sorgt für eine Art "equals" Methode (ist vor allem für mdSet wichtig, da keine Duplikate vorkommen dürfen). Bei letzteren kannst du dir das leben einfach machen, indem du einfach ein Return Str(lhs) = Str(rhs) einbaust, weil das Cast hast du ja sowieso.
mdListDeclare(MyClass) löst das Macro für den angegebenen Type auf. Erst dadurch ist das nutzbar.
Dim As mdList(MyClass) list ist dann einfach nur die Deklaration einer Liste. Im Prinzip ist das nur Syntax-Zucker, du kannst auch Dim as mdListMyClass list machen, ist exakt das gleiche.
foo ist ein Musterobjekt, das hast du richtig erkannt. Das passe ich an und gebe es der Liste mit geänderten Werten. Die Liste übernimmt eine Kopie des Objekts mit dem aktuellen Zustand.
add() liefert nur TRUE oder FALSE zurück, ja, allerdings ist size()-1 natürlich richtig, weil add() immer ans Ende der Liste hängt. Es gibt aber auch die indexOf(...) Methode, wenn du etwas suchst. Auch hierfür ist der Vergleichsoperator wichtig, den du für deine Klasse bauen musst.
Je nachdem, wie du durch die Liste gehen willst, brauchst du aber nicht zwingend einen Index. Die drei Output-Beispiele in dem Code machen es vor. Den Index brauchst du erst dann wieder, wenn du Objekte innerhalb der Liste an einer bestimmten Stelle mit set(...) ersetzen willst. |
|
Nach oben |
|
|
Muttonhead
Anmeldungsdatum: 26.08.2008 Beiträge: 562 Wohnort: Jüterbog
|
Verfasst am: 31.01.2014, 14:03 Titel: |
|
|
jaja... die drei outputs rattern die ganze Liste ab. Schön und gut.
Ich will den Eintrag den ich mit
Code: |
foo.myVar = 3 : list.add(foo)
|
"geadded" habe auf 25 ändern?
ich brauch doch iwie zugriff...
Mutton |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 31.01.2014, 14:20 Titel: |
|
|
Wenn du absolut nicht weißt, wo das Element liegt, musst du dir den Index besorgen. Dafür nimmst du das ursprüngliche Element (oder definierst deinen Vergleichsoperator entsprechend) und machst dann sowas: altesElement = list.set(list.indexOf(altesElement), neuesElement)
Falls du tatsächlich sowas wie Keys halten willst, dann würdest du aber eher eine mdMap nehmen, da hast du immer ein Key-Value-Paar.
Alternativ kannst du das Listeverhalten komplett ändern, indem du die Parts überschreibst, die dir nicht gefallen. Ein Beispiel dazu: nemoredsList |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 31.01.2014, 14:46 Titel: |
|
|
die aber zunächst einmal nichts mit dem gleichnamigen Forenmitglied zu tun hat.
Ich hatte bisher im großen und ganzen zwei Szenarien:
Zum einen, dass ich die komplette Liste durchlaufe, die Einträge einzeln auslese, ggf. ändere und dann zurückschreibe. In diesem Fall hast du den Index sowieso immer parat.
Im anderen Fall will ich den Eintrag bearbeiten, der bestimmte Eigenschaften hat - dazu suche ich den Index des entsprechenden Eintrags (wohl über IndexOf; ich habe die Befehlsliste nicht im Kopf). Um mdList zu nutzen, musst du u. a. einen Vergleichsoperator bereitstellen; den musst du dann eben so gestalten, dass das Objekt an den vorgesehenen Eigenschaften "eindeutig" erkennbar ist. In deinem Beispiel etwa "ändere den Eintrag, in dem myVar auf 3 steht" - dann muss dein Vergleichsoperator auf die Identität von myVar prüfen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Muttonhead
Anmeldungsdatum: 26.08.2008 Beiträge: 562 Wohnort: Jüterbog
|
Verfasst am: 31.01.2014, 16:39 Titel: |
|
|
nemored hat Folgendes geschrieben: | .....
Im anderen Fall will ich den Eintrag bearbeiten, der bestimmte Eigenschaften hat - dazu suche ich den Index des entsprechenden Eintrags (wohl über IndexOf; ich habe die Befehlsliste nicht im Kopf). Um mdList zu nutzen, musst du u. a. einen Vergleichsoperator bereitstellen; den musst du dann eben so gestalten, dass das Objekt an den vorgesehenen Eigenschaften "eindeutig" erkennbar ist. In deinem Beispiel etwa "ändere den Eintrag, in dem myVar auf 3 steht" - dann muss dein Vergleichsoperator auf die Identität von myVar prüfen. |
scheint mir doch sehr unpraktikabel zu sein,innerhalb der Liste nach dem Wert einer bestimmten Eigenschaft zu suchen: zwei Strukturen die beispielsweise für 2 Trackbars stehen die zufälligerweise den gleichen Scrollwert haben... *kopfkratz* Wobei ich das Prinzip des Vergleichsoperators noch nicht begriffen hab. Als Alternative könnte ich natürlich nen eigenen Eintragscounter als Eigenschaft definieren und nach diesem suchen. Dann wäre der zu suchende Eintrag eindeutig.
Alles in allem habe ich aber das Gefühl in einem Pool "listed lost data" zu fischen. Das liegt aber an meinem Unwissen und absolut nicht bös gemeint!
Mutton |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 31.01.2014, 18:20 Titel: |
|
|
Deine Scrollbar wird sich wohl eher durch eine ID oder ihren Namen (also ID ...) identifizieren lassen. In diesem Fall gibt der Operator Gleichheit zurück, wenn die ID übereinstimmt. Unterschied im Vergleich zum Index macht das ja erst, wenn du zwischendrin mal einen Eintrag aus der Liste löscht oder verschiebst.
Wenn du mal genau das Szenario schilderst, auf das du hinaus willst, kann ich vielleicht einen Denkanstoß geben.
P. S.: Falls du das Objekt anhand seiner Position bestimmen willst, würde ich alle Objekte der Liste durchlaufen und das erste nehmen, bei dem die Position passt (zumindest solange ich mir keine Sorgen um Überlappungen machen muss ). _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 31.01.2014, 18:34 Titel: |
|
|
Einfaches Beispiel:
Code: | Type Widget
Public:
Declare Operator Cast() As String
As Integer id
As String name
As Integer scrollValue
End Type
Operator Widget.Cast() As String
Return Str(id) & name & Str(scrollValue)
End Operator
Operator = (ByRef lhs As Widget, ByRef rhs As Widget) As Integer
Return Str(lhs) = Str(rhs)
End Operator
Dim As Widget a, b
a.id = 500
a.name = "Superwidget"
a.scrollValue = 23
b.id = 783
b.name = "Another superwidget"
b.scrollValue = 23
If a = b Then
Print "a und b sind gleich"
Else
Print "a und b sind nicht gleich"
EndIf
Sleep |
Obwohl der Scrollvalue gleich ist, sind die anderen Werte es nicht. Der Vergleichsoperator muss genau das berücksichtigen, was ein Widget eindeutig vom anderen unterscheiden kann.
In dem Beispiel würde man den Scrollvalue vermutlich gar nicht für den Vergleich berücksichtigen, da er absolut kein eindeutiger Wert ist. Die ID und/oder Name sollte dagegen nicht mehrfach vorkommen. Die ID kann ja auch ganz simpel der Pointer auf das Widget sein, der Pointer ist immer eindeutig und somit von allen anderen Widgets unterscheidbar. |
|
Nach oben |
|
|
Muttonhead
Anmeldungsdatum: 26.08.2008 Beiträge: 562 Wohnort: Jüterbog
|
Verfasst am: 31.01.2014, 20:34 Titel: |
|
|
@MOD:
aha... das sieht sehr gut aus ... doch, damit könnte ich arbeiten |
|
Nach oben |
|
|
|