Wie geht ihr mit Überladung um?

Anfängerfragen zum Programmieren mit PureBasic.
s91
Beiträge: 20
Registriert: 07.09.2022 17:20
Wohnort: HY

Wie geht ihr mit Überladung um?

Beitrag von s91 »

Was hat PureBasic zu bieten um Überladungen zu "simulieren"?

Das Überladen einer Prozedur bedeutet, sie in mehreren Versionen zu definieren, wobei derselbe Name, aber verschiedene Parameterlisten verwendet werden. Der Zweck der Überladung besteht darin, mehrere eng verwandte Versionen eines Verfahrens zu definieren, ohne sie nach Namen unterscheiden zu müssen. [...]
von: https://learn.microsoft.com/de-de/dotne ... verloading

Daraus dass PureBasic keine Überladung ermöglicht, schlussfolgere ich:

- die unterschiedlichen Verfahrensversionen müssen per Namen unterschieden werden, es sei denn es ermöglichen sich bedingte Teilverfahren per optionalen Parametern (was aber einen gehörigen Unterschied zur Überladung darstellen kann)
- enge Verwandschaft zwischen Verfahrensversionen kann umständlicher geschaffen werden, indem alle Parameter außerhalb der Funktion (etwa "global") festgeschrieben werden und die Funktion selbst dann alle Fallunterscheidungen unternimmt um die Datenlage zu klären (zum Beispiel: untersucht, was alles bei #null oder #empty$ steht).

Für letzteren Punkt gibt es da eine Problematik: alle Parameternamen müssen ja innerhalb eines die Funktion umgebenden Namensraumes erkennbar definiert sein (außer bei Kleinstprogrammen) und in die Funktion eingebunden werden. Was ist dafür besser, "global" oder "shared", bzw. gibt es da überhaupt einen zu beachtenden Unterschied?

Hattet Ihr mal Fälle in denen Soetwas relevant wurde und wie seid Ihr damit umgegangen? Und: Könnte man auf Maschinencodeebene feststellen, dass es herstellergemachte Geschwindigkeitsunterschiede zwischen VBs Überladungen und PBs expliziteren Wegen gibt?
auf smartphones und tablets kann es zu kleingeschriebenen substantiven, mangelhafter zeichensetzung und schlechtem englisch kommen / i ask for apology
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Wie geht ihr mit Überladung um?

Beitrag von STARGÅTE »

Um vielleicht etwas besser darauf antworten zu können wäre meine Gegenfrage, welches Beispiel schwebt dir gerade vor?

Zu deinem ersten Punkt besteht in PureBasic ja die Limitierung, dass es gar nicht möglich ist, im gleichen Parameterindex verschiedene Typen zu übergeben: Zahl, String, Liste, Map, Array usw.
Somit ist das schlichtweg so gar nicht möglich.
Zu deinem zweiten Punkt würde ich stark davon abraten die Prozedur nur als Caller zu nutzen und Globale Variaben als Parameter zu nutzen. Grund ist, dadurch fallen so simple Sache wie Rekursion weg.

Ich selbst habe das Überladen in PureBasic dadurch "simuliert", dass ich im Endeffekt immer nur Pointer zu den "Objekten" übergeben habe und das Objekt selbst Infos darüber trug was es ist.
s91 hat geschrieben: 20.12.2022 16:37 Könnte man auf Maschinencodeebene feststellen, dass es herstellergemachte Geschwindigkeitsunterschiede zwischen VBs Überladungen und PBs expliziteren Wegen gibt?
Definitiv. Soweit ich das richtig verstanden habe, sind echte Überladungen ja auf Kompiler-Ebene, dass heißt, beim kompilieren wird sich schon je nach Type des Parameters für eine Version entschieden. In PureBasic wäre das immer erst zur Laufzeit möglich für Abfragen.

Alternativ kann man aber Macros nutzen, die alle Versionen sozusagen umhüllen und dann zur Compilerzeit die passenden finden. Das geht dann aber auch nur sehr eingeschränkt:

Code: Alles auswählen

Macro MyPrintN(param)
	CompilerSelect TypeOf(param)
		CompilerCase #PB_String
			PrintN(param)
		CompilerCase #PB_Integer
			PrintN(Str(param))
		CompilerCase #PB_Float
			PrintN(StrF(param))
	CompilerEndSelect
EndMacro


Define MyString.s = "Hallo"
Define MyInteger.i = 123
Define MyFloat.f = 3.14

OpenConsole()
MyPrintN(MyString)
MyPrintN(MyInteger)
MyPrintN(MyFloat)
Input()
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
jacdelad
Beiträge: 404
Registriert: 03.02.2021 13:39
Wohnort: Riesa
Kontaktdaten:

Re: Wie geht ihr mit Überladung um?

Beitrag von jacdelad »

Ich denke, die einzige und recht einfache Variante ist, es wie bei den Windows APIs zu machen: Einen strukturierten Speicherbereich definieren, in das erste Element die Größe/Version eintragen und dann die entsprechenden Werte. Der Bereich ist somit von Version zu Version erweiterbar. Das ist zwar keine echte Überladung in dem Sinn, aber genauso nutzbar.
Guten Morgen, das ist ein schöner Tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3 TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Wie geht ihr mit Überladung um?

Beitrag von NicTheQuick »

...womit man schon kurz davor ist OOP zu nutzen. Man hat strukturierte Objekte und übergibt diese den Prozeduren, die dann entscheiden, was mit dem Objekt getan werden muss. Die Fallunterscheidung kann man sich sparen, indem man Interfaces nutzt und für jeden Objekttyp gleich mitliefert welche Methode für ihn benutzt werden soll.

Noch ein Hinweise bezüglich der globalen Variablen. Neben dem von Stargate angesprochenen Problem der Rekursion hast du damit auch ein Problem mit Threads. Wenn du einfach jedes "Global" mit "Threaded" ersetzt, ist das aber gelöst. Rekursion geht dann aber immer noch nicht.
Antworten