Autor Beitrag
M.Mü
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 68



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 162

Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
BeitragVerfasst: 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ü Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 68



BeitragVerfasst: Do 08.01.09 14:03 
Habs grad mit Interfaces probiert ... leider gehts net.

Und zwar schimpft der Compiler bei folgendem TypeCast.

ausblenden 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; // <- Fehler
  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.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  p: pointer

  p := TSlaveA.Create;
  ISlaveA(P).Machwas;         // <- Fehler
  ISlaveA(TSlaveA(p)).Machwas // <- OK


Also ginge
ausblenden 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 user profile iconmatze: Code- durch Delphi-Tags ersetzt
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: Do 08.01.09 18:23 
Funktioniert
ausblenden 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ü Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 68



BeitragVerfasst: 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?

ausblenden Quelltext
1:
2:
3:
4:
  p: pointer

  p := TSlaveA.Create;
  ISlaveA(p).Machwas;


:?: :?: :?:
hazard999
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 162

Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
BeitragVerfasst: Fr 09.01.09 08:49 
Nimm keinen pointer.

Nicht notwendig.

ausblenden 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ü Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 68



BeitragVerfasst: 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. :bawling:

TList besteht ja nun mal nur aus Pointern ...
M.Mü Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 68



BeitragVerfasst: Fr 09.01.09 11:35 
Korrektur: (irgendwas as Interface) funktioniert doch, allerdings nur mit dem direkt abgeleiteten Datentyp

ausblenden 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;     // OK
  (s as ISlaveA).Machwas  // OK
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: 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.