Stringrückgabe in PB-"Klassen"

Für allgemeine Fragen zur Programmierung mit PureBasic.
es_91
Beiträge: 411
Registriert: 25.01.2011 04:48

Stringrückgabe in PB-"Klassen"

Beitrag von es_91 »

Ich bin am Verzweifeln. Warum erhalte ich irgendeine Nummer und nicht den "Hallo, Welt"-String?

Code: Alles auswählen

Interface Str
  
  Delete ()
  String ()
EndInterface

DeclareModule Str
  
  Declare New (String$ = #Empty$)
EndDeclareModule

Module Str
  
  Structure SString
    
    *VTABLE
    
    String$
  EndStructure
  
  Procedure IDelete (*this. SString)
    
    FreeMemory (*this)
  EndProcedure
  
  Procedure New (String$ = #Empty$)
    
    Protected *this. SString
    
    *this = AllocateMemory (SizeOf (SString))
    
    If *this
      
      *this \ VTABLE = ? VTABLE_SSTRING
      
      *this \ String$ = String$
      
      ProcedureReturn *this
    EndIf
  EndProcedure
  
  Procedure$ IString (*this. SString)
    
    ProcedureReturn *this \ String$
  EndProcedure
  
  DataSection
    
    VTABLE_SString:
    
    Data. i @ IDelete ()
    Data. i @ IString ()
  EndDataSection
EndModule

Text. Str = Str::New ("Hallo, Welt!")

Debug Text \ String ()
Zur Erläuterung: Das ist der Versuch, PureBasics Kniffe-und-Tricks-Ecke soweit auszureitzen, dass es beinahe OOP ermöglicht.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7035
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Stringrückgabe in PB-"Klassen"

Beitrag von STARGÅTE »

Strings sind dynamische Objekte und müssen in Strukturen die du selbst erstellst initialisiert werden.
Außerdem musst du bei deinem Interface bei den Prozeduren (bzw. Methoden) den RückgabeTyp angeben.
Also:

Code: Alles auswählen

Interface Str
  Delete ()
  String.s () ; für Strings wie in Procedure.s IString() bzw. Procedure$ IString()
EndInterface
und weiter unten

Code: Alles auswählen

*this = AllocateStructure(SString)
AllocateStructure() kannst du später auch gut gebrauchen, wenn du zB Arrays und Listen benutzt.
Außerdem dann auch bei freigeben:

Code: Alles auswählen

FreeStructure (*this)
damit auch die Strings gelöscht werden.

Edit: hier noch ein anderes weiterführendes Beispiel:

Code: Alles auswählen

Interface Statistic
	Add(Value.f)
	Count.i()
	Free()
	Mean.f()
	String.s()
EndInterface

DeclareModule Statistic
	Declare.i New()
EndDeclareModule

Module Statistic
	
	Structure StatisticData
		*Methodes
		List Value.f()
	EndStructure
	
	Procedure Add(*This.StatisticData, Value.f)
		AddElement(*This\Value())
		*This\Value() = Value
	EndProcedure
	
	Procedure.i Count(*This.StatisticData)
		ProcedureReturn ListSize(*This\Value())
	EndProcedure
	
	Procedure.i Free(*This.StatisticData)
		FreeStructure(*This)
	EndProcedure
	
	Procedure.f Mean(*This.StatisticData)
		Protected Sum.f
		ForEach *This\Value()
			Sum + *This\Value()
		Next
		ProcedureReturn Sum / Count(*This)
	EndProcedure
	
	Procedure.s String(*This.StatisticData)
		Protected String.s
		If FirstElement(*This\Value())
			String = StrF(*This\Value())
			While NextElement(*This\Value())
				String + ", "+StrF(*This\Value())
			Wend
		EndIf
		ProcedureReturn String
	EndProcedure
	
	Procedure.i New()
		Protected *This.StatisticData = AllocateStructure(StatisticData)
		*This\Methodes = ?Methodes
		ProcedureReturn *This
	EndProcedure

	DataSection
		Methodes:
		Data.i @Add()
		Data.i @Count()
		Data.i @Free()
		Data.i @Mean()
		Data.i @String()
	EndDataSection
	
EndModule


Table.Statistic = Statistic::New()
Table\Add(2.0)
Table\Add(4.0)
Table\Add(5.0)
Debug Table\String()
Debug Table\Count()
Debug Table\Mean()
Table\Free()
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
es_91
Beiträge: 411
Registriert: 25.01.2011 04:48

Re: Stringrückgabe in PB-"Klassen"

Beitrag von es_91 »

STARGÅTE, vielen Dank für Deine zahlreichen Tipps und für schnelle Hilfe mitten in der Nacht! Super informativ und nett zu lesen. :allright:

Der Primärfehler lag also in Zeile 4 meines Beispielprogramms, die dortige Interface-Deklaration muss lauten:

Code: Alles auswählen

Interface Str

  Delete ()
  String. s ()
EndInterface
Danke. :D
Antworten