Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

15.07.2017, 15:29

Referenz auf Basisklasse-Problem!

Hallo Leute,

ich habe eine wichtige Verständnisfrage zu Verweisübergaben in Bezug auf Vererbung/Polymorphismus!!

Ich habe folgendes Codebeispiel bzw. folgende Beispielarchitektur:

//Pseudocode:
Klasse TGhost: //TGhost ist instanziierbar!
Name = String
Groesse = Byte;

Methode Spuken();
{
//BUUUH...
}

Jetzt haben wir noch 2 verschiedene Ableitungen von der TGhost und zwar: TCannibalGhost und TSlimeGhost.
TCannibalGhost
kann extra noch andere Geister Essen, das sieht so aus: Methode Eat(ref TGhost andererGeist) und TSlimeGhost kann noch extra eine Schleimspur hinterlassen, via: Methode Slime()...

Mein Problem jetzt ist:

wenn TCannibalGhost JEDEN anderen Geist essen kann gibt es ja bekanntlich das Dilemma zwischen Referenzparameter und Vererbung was ja korrekterweise nicht kompiliert!

Aber was ist, wenn ich sage: Eat(ref TGhost andererGeist) und ihm auch eine Instanz von TGhost übergebe, was ja noch OK ist, aber DANN in der Methode setze ich "andererGeist" einfach auf eine Instanz von TSlimeGhost, also: "andererGeist = new TSlimeGhost(Name:'slimey', Groesse: 10);"

Das wird kompiliert, ist doch aber semantischer Unsinn, weil eine übergebene Instanz von TGhost NICHT eine Instanz von TSlimeGhost sein kann oder irre ich mich?
[/b]

Wäre über eine Aufklärung sehr erfreut!

LG

PF

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

15.07.2017, 15:37

Natürlich kann sie das sein, wenn das die Basisklasse ist. Ein Schleimgeist ist schließlich auch ein Geist. "andererGeist" ist irgendein Geist-Typ, das ist auch total legal da einen Schleimgeist zuzuweisen, selbst wenn das vorher ein Poltergeist war. (Wir reden hier über C#, ja? Bei C++ kann sowas böse Aua geben.)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

15.07.2017, 15:45

Also meinst Du, wenn ich in der Eat-methode einen TSlimeGhost übergeben bekomme und in der Eat-Methode diese übergebene Instanz dann auf eine Basisklasseninstanz zeigen lasse, ist das Ok?

EDIT:
Ja, ich rede eigentlich von C#, aber in Pascal habe ich da auch Mist bekommen und wie wäre es dann in C++?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

15.07.2017, 15:51

In C# sind alles Referenzen. Übergibst du einen SlimeGhost nur als Ghost (ehrlich, das T-Präfix is doch Käse) und das noch via ref, dann wäre es natürlich ein Problem, wenn du da einen anderen Typ zuweist. Generell ist das Zuweisen eines Untertyps an eine Basis-Typ-Variable natürlich kein Problem. Das Problem entsteht erst dann, wenn du einen unsichtbaren "Cast" durchführen willst. 'ref' ist in C# generell eigentlich nur selten wirklich sinnvoll. Also folgende Unterschiede:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
void changeIt(ref Ghost ghost) {
  ghost = new KillerGhost();
}
Ghost ghost = new SlimeGhost();
SlimeGhost slimer = new SlimeGhost();
changeIt(ref ghost); // total OK, die Typen passen, nur ist "ghost" halt hinterher ein KillerGhost.
changeIt(ref slimer); // NICHT OK, weil die Funktion versucht einem SlimeGhost einen KillerGhost zuzuweisen und es durch den Cast nicht merkt

Ghost slimer2 = slimer;
changeIt(ref slimer2); // total OK, slimer2 ist hinterher ein Killer, slimer weiterhin ein Slimer

Ghost slimerKiller = new SlimerGhost();
slimerKiller = new KillerGhost(); // total OK, sind ja alles Geister
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von »BlueCobold« (15.07.2017, 16:04)


5

15.07.2017, 16:14

Entschuldige, aber ich verstehe irgendwie einfach nicht, wieso das mit dem "ref" ein Problem ist ohne "ref" ist das ok :wacko: :wacko:

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

15.07.2017, 16:44

Ohne ref handelt es sich um eine lokale Variable vom Typ Ghost. Mit ref handelt es sich um eine Variable, die behauptet sie sei vom Typ Ghost, aber eigentlich vom Typ SlimeGhost ist. Letzteres kann so nicht funktionieren.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige