| Autor |
Beitrag |
M.Mü
      
Beiträge: 68
|
Verfasst: Do 08.01.09 11:37
Hallo,
ich halbe folgendes Problem. Leider kann ich den Quellcode nicht posten, da er zu Umfangreich ist ... also versuch ich es mal abstrakt darzulegen. Im großen und ganzen geht es um das MVC-Pattern.
Es gibt einen UrMaster der eine Liste von UrSlaves enthält. Von ihnen abgeleitet gibt es einen MasterA und einen MasterB bzw. einen SlaveA und einen SlaveB. Wie zu vermuten ist, kann MasterA nur mit SlaveA und MasterB nur mit SlaveB arbeiten. (Dies geschieht logischerweise durch einen TypeCast, da die Master ja nur die Liste des UrMasters enthalten.)
Nun bräucht ich einen SlaveAB, d.h. er muss die Funktionen von A und B vereinen. Problem dabei ist, dass die Funktionen auch noch voneinander abhängen, bzw. sich die Slaves Werte vom Master holen.
Das einzige, was mir bis jetzt eingefallen ist, SlaveA und SlaveB so umzuschreiben, dass ich die Funktionen als Eigenschaften zuweisen könnte. Ich würde dann eine Klasse SlaveAB schreiben, die SlaveA und SlaveB als Objekte enthält und die entsprechenden Funktionen zuweisen.
Kann mir jemand helfen? Oder besser ... versteht jemand mein Problem?
VG M.Mü
|
|
hazard999
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: Do 08.01.09 12:16
Hmm.
Ich würd mal sagen du brauchst Mehrfachvererbung.
Geht nur nicht.
Probiers mal mit Interfaces.
Da hast du dann wenigstens die Methoden-Signatur.
_________________ MOV EAX, Result;MOV BYTE PTR [EAX], $B9;MOV ECX, M.Data;MOV DWORD PTR [EAX+$1], ECX;MOV BYTE PTR [EAX+$5], $5A;MOV BYTE PTR [EAX+$6], $51;MOV BYTE PTR [EAX+$7], $52;MOV BYTE PTR [EAX+$8], $B9;MOV ECX, M.Code;MOV DWORD PTR [EAX+$9], ECX
|
|
M.Mü 
      
Beiträge: 68
|
Verfasst: Do 08.01.09 14:03
Habs grad mit Interfaces probiert ... leider gehts net.
Und zwar schimpft der Compiler bei folgendem TypeCast.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| ISlaveA = interface ... end;
TSlaveA = class(TSlave, ISlaveA) ... end;
...
procedure MasterA.Machwas; begin ISlaveA(FSlaveList[i]).Machwas; end; |
Habs dann noch etwas einfacher probiert, und es scheint so zu sein, dass man einen TypeCast zum einem Interface nur von der Klasse aus machen kann.
Delphi-Quelltext 1: 2: 3: 4: 5:
| p: pointer
p := TSlaveA.Create; ISlaveA(P).Machwas; ISlaveA(TSlaveA(p)).Machwas |
Also ginge
Delphi-Quelltext 1:
| ISlaveA(TSlaveA(FSlaveList[i])).Machwas; |
Dies macht aber keinen Sinn, da TSlaveA gerade das ist, was variiert.
Selbst bei einem Pointer der vom Typ TSlave ist, funktioniert es nicht. Hab ich da die Interfaces falsch verstanden, oder ist dem tatsächlich so?
Moderiert von matze: Code- durch Delphi-Tags ersetzt
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Do 08.01.09 18:23
Funktioniert
Delphi-Quelltext 1: 2: 3: 4:
| p: pointer
p := TSlaveA.Create; (P as ISlaveA).Machwas; |
?
Hab's nicht getestet ob man Pointer so casten kann...
|
|
M.Mü 
      
Beiträge: 68
|
Verfasst: Fr 09.01.09 00:04
@baka0815
Nein, so gehts auch nicht ... Fehlermeldung: [Pascal Fehler] Unit1.pas(45): E2015 Operator ist auf diesen Operandentyp nicht anwendbar
Hab leider mit Interfaces noch keine große Erfahrung ...
Im Grunde lautet nun die Frage: Warum geht dieser TypeCast nicht?
Quelltext 1: 2: 3: 4:
| p: pointer
p := TSlaveA.Create; ISlaveA(p).Machwas; |

|
|
hazard999
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: Fr 09.01.09 08:49
Nimm keinen pointer.
Nicht notwendig.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var o : TObject; begin o := TSlaveA.Create; (o as ISlaveA).Machwas; end; |
sollte gehen.
_________________ MOV EAX, Result;MOV BYTE PTR [EAX], $B9;MOV ECX, M.Data;MOV DWORD PTR [EAX+$1], ECX;MOV BYTE PTR [EAX+$5], $5A;MOV BYTE PTR [EAX+$6], $51;MOV BYTE PTR [EAX+$7], $52;MOV BYTE PTR [EAX+$8], $B9;MOV ECX, M.Code;MOV DWORD PTR [EAX+$9], ECX
|
|
M.Mü 
      
Beiträge: 68
|
Verfasst: Fr 09.01.09 11:29
hmmm ...
die Konstruktion ( irgendwas as Interface) ist anscheinend nicht erlaubt. Immer wenn ich es auf Interfaces anwende, kommt die Fehlermeldung [Pascal Fehler] Unit1.pas(45): E2015 Operator ist auf diesen Operandentyp nicht anwendbar.
auch mit TObject gehts net ... Die Fehlermeldung lautet dann inkompatible Typen. Es scheint halt doch nur mit den direkt abgeleiteten Datentypen zu funktionieren. Es ist zum heulen.
TList besteht ja nun mal nur aus Pointern ...
|
|
M.Mü 
      
Beiträge: 68
|
Verfasst: Fr 09.01.09 11:35
Korrektur: (irgendwas as Interface) funktioniert doch, allerdings nur mit dem direkt abgeleiteten Datentyp
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| ISlaveA = interface end;
TSlaveA = class(TSlave, ISlaveA) end;
s: TSlaveA ; s:=TSlaveA .Create; ISlaveA(s).Machwas; (s as ISlaveA).Machwas |
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Fr 09.01.09 16:18
Was du möchtest ist jedoch nicht S: TSlaveA, sondern S: ISlaveA, somit kann S von allem sein, was das Interface ISlaveA implementiert.
|
|
|