Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

mehrere types durch ein "Listobjekt" verwalten

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 561
Wohnort: Jüterbog

BeitragVerfasst am: 29.01.2014, 22:01    Titel: mehrere types durch ein "Listobjekt" verwalten Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 30.01.2014, 08:07    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2507
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 30.01.2014, 20:41    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 561
Wohnort: Jüterbog

BeitragVerfasst am: 31.01.2014, 11:22    Titel: Antworten mit Zitat

@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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 31.01.2014, 12:40    Titel: Antworten mit Zitat

Im Hintergrund wird ein gigantisches Macro zu einer komplexen hierarchischen Vererbungsstruktur aufgelöst.happy
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. zwinkern

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
Benutzer-Profile anzeigen Private Nachricht senden
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 561
Wohnort: Jüterbog

BeitragVerfasst am: 31.01.2014, 13:03    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 31.01.2014, 13:20    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 31.01.2014, 13:46    Titel: Antworten mit Zitat

die aber zunächst einmal nichts mit dem gleichnamigen Forenmitglied zu tun hat. grinsen

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
Benutzer-Profile anzeigen Private Nachricht senden
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 561
Wohnort: Jüterbog

BeitragVerfasst am: 31.01.2014, 15:39    Titel: Antworten mit Zitat

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! lächeln

Mutton
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 31.01.2014, 17:20    Titel: Antworten mit Zitat

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. lächeln

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 happy).
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 31.01.2014, 17:34    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Muttonhead



Anmeldungsdatum: 26.08.2008
Beiträge: 561
Wohnort: Jüterbog

BeitragVerfasst am: 31.01.2014, 19:34    Titel: Antworten mit Zitat

@MOD:
aha... das sieht sehr gut aus lächeln... doch, damit könnte ich arbeiten
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz