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

19.07.2011, 15:51

Problem mit Memberfunktionen

Ok, gleich das nächste Problem von mir:

Ich möchte mittels eines Zeigers eine Instanz einer Klasse erstellen, die von einer anderen Klasse einige Funktionen erbt.

Unteranderem hat die Oberklassen eine membervariable für einen Namen und eine Funktion, mit der man diesen Namen bestimmen kann:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
class C_Raumschiff
{
    protected:
    char m_Name[50];

    public:
    void m_RaumschiffBenennen();
};


C-/C++-Quelltext

1
2
3
4
5
6
void C_Raumschiff::m_RaumschiffBenennen()
{
    cout << "Geben sie ihrem Raumschiff einen Namen: " << endl;
    cin.ignore();
    cin.get (m_Name, 49);
}


Nun soll in einer weiteren Datei das Raumschiff benannt werden:

C-/C++-Quelltext

1
2
3
4
5
SpielerRaumschiff = new C_Jaeger;
                    *Kontostand -= JaegerPreis;
                    RaumschiffGekauft = true;
                    cout << "Ihr derzeitiger Kontostand: " << *Kontostand << endl;
                    SpielerRaumschiff.m_RaumschiffBenennen();//hier liegt der Fehler


Hier noch ein Auszug aus der main Funtion:

C-/C++-Quelltext

1
2
3
C_Raumschiff *p_SpielerRaumschiff = 0;// das Raumschiff des Spielers

    RaumschiffKaufen(&i_Kontostand, p_SpielerRaumschiff);


Wenn ich über SpielerRaumschiff drüberfahre, steht da, dass der Ausdruck einen Klassentyp aufweisen muss.
Im Buch "C++ für Spieleprogrammierer" wird praktisch das selbe gemacht, da funktioniert es dann auch ?( .

Dann habe ich ja den Zeiger mit C_Raumschiff deklariert.
Was muss ich nun tun, um die Funtionen von C_Jaeger nutzen zu können?

2

19.07.2011, 16:16

Hallo,

ich bin mir bei diesen Quellcode-Schnippseln nicht ganz sicher, aber was hat C_Raumschiff *p_SpielerRaumschiff mit SpielerRaumschiff = new C_Jaeger; zu tun?
p_SpielerRaumschiff ist ein Zeiger auf ein Objekt der Klasse C_Raumschiff. Der Zeiger kann nicht auf ein Objekt der Klasse C_Jaeger zeigen, auch nicht wenn diese Klasse von C_Raumschiff erbt.

Quellcode Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class C_Raumschiff     // Basis-Klasse für ein Raumschiff
{
protected:
     int m_Treibstoff;

public:
     void WieVielTreibstoff();
};

class C_Jaeger : public C_Raumschiff     //  Diese Klasse erbt die Member von C_Raumschiff
{
protected:
     int m_Torpedos;

public:
     void WieVieleTorpedos();
};


void KaufeJaeger(C_Jaeger* pNeuerJaeger)     // Mit dieser Funktion wird ein neues Raumschiff vom Typ C_Jaeger gekauft
{
     pNeuerJaeger = new C_Jaeger;
     pNeuerJaeger->WieVielTreibstoff();     // Hier wird die von C_Raumschiff geerbte Methode aufgerufen.
}

void KaufeRaumschiff(C_Raumschiff* pNeuesRaumschiff)     // Mit dieser Funktion soll ein neues Raumschiff gekauft werden.
{
     pNeuesRaumschiff = new C_Jaeger;   // Das hier funktioniert nicht! Ein Zeiger für C_Raumschiff kann nicht auf C_Jaeger zeigen.
     pNeuesRaumschiff->WieVielTreibstoff();
}

int main ()
{

     // Funktioniert:
     CJaeger* pJaeger = NULL;

     KaufeJaeger(pJaeger);

     pJaeger->WieVieleTorpedos();

     // Funktioniert nicht:
     CRaumschiff* pRaumschiff = NULL;

     KaufeRaumschiff(pRaumschiff);

     pRaumschiff->WieVieleTorpedos();

     return 0;
}


Vielleicht verdeutlicht das noch mal wie du in deinem Fall mit Klassen, Zeigern und Vererbung umgehen musst.

Gruß
SaRu_

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »SaRu« (19.07.2011, 16:29)


3

19.07.2011, 16:39

Ich habe diese Art der Zuweisung so aus dem Buch "C++ für Spieleprogrammierer 8| .

Hier der entprechende Part:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main ()
{
    // Variablen
    //
    CRaumschiff *Schiff; // Ein Raumschiff

    Schiff = new CMinenleger; // Ein Minenleger soll es sein

    // Minenleger führt einige Aktionen aus
    Schiff->Starten ();
    Schiff->Landen ();

    delete Schiff;  // Raumschiff zerstören

    return 0;


Hier zeigt doch auch ein Zeiger der Klasse CRaumschiff auf eine Instanz der Klasse CMinenlger?
Also wenn ich das richtig verstanden habe :whistling:

Edit: Ich habe jetzt einfach mal den ->(Auch wenn ich nicht weiß was das genau ist ) verwendet, un es klappt alles 8| .
Auch wenns so vielleicht nicht gedacht war danke dafür :thumbsup: .

Frage 1 wäre damit schon beantwortet :P

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Rexona for men« (19.07.2011, 16:47)


drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

19.07.2011, 16:46

SpielerRaumschiff.m_RaumschiffBenennen();//hier liegt der Fehler

C-/C++-Quelltext

1
SpielerRaumschiff->m_RaumschiffBenennen();
?

5

19.07.2011, 16:48

In der Zeile mit dem Fehler hast du anscheinend einen Zeiger (siehe 4 Zeilen weiter oben). Du musst also zuerst dereferenzieren oder gleich den -> Operator verwenden.

C-/C++-Quelltext

1
2
SpielerRaumschiff->m_RaumschiffBenennen();//hier lag der Fehler
(*SpielerRaumschiff).m_RaumschiffBenennen();//hier lag der Fehler


Edit: Zu spät. Was war denn die zweite Frage, wenn die erste somit beantwortet wurde? Evtl. das?

Zitat von »SaRu«

Der Zeiger kann nicht auf ein Objekt der Klasse C_Jaeger zeigen, auch nicht wenn diese Klasse von C_Raumschiff erbt.

Doch, das ist möglich.

6

19.07.2011, 16:53

Die zweite war, wie ich in diesem Fall auf die Memberfunktionen der Klasse C_Jaeger zurückgreife.
Geraten: Ich muss den -> Operator verwenden?

Die nun dritte ist, was ist das: -> :D

Und noch was, wann verwende ich den . und wenn den -> wenn ich auf memberfunktionen zurückgreife?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Rexona for men« (19.07.2011, 17:02)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

7

19.07.2011, 17:10

p_SpielerRaumschiff ist ein Zeiger auf ein Objekt der Klasse C_Raumschiff. Der Zeiger kann nicht auf ein Objekt der Klasse C_Jaeger zeigen, auch nicht wenn diese Klasse von C_Raumschiff erbt.

Natürlich kann er! Das macht allerdings nur in Verbindung mit virtuellen Methoden(besonders wenn man über diesen Zeiger deletet sollte der Destruktor als virtual deklariert worden sein), RTTI oder als Funktionsparameter sinn. Ich kann deinen Protest verstehen, denn für den Threadersteller machts wahrscheinlich noch keinen Sinn^^
Allerdings solltest du den angeforderten Speicher auch in deinen Beispielen auch wieder freigeben...

@Rexona: Diese beiden Zeilen machen genau das gleiche.

C-/C++-Quelltext

1
2
SpielerRaumschiff->m_RaumschiffBenennen();//hier lag der Fehler
(*SpielerRaumschiff).m_RaumschiffBenennen();//hier lag der Fehler

Der Zugriffsoperator -> dereferenziert den Zeiger auf das Objekt also automatisch, spart dir somit nur etwas Tipparbeit und macht den Code etwas übersichtlicher.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »NachoMan« (19.07.2011, 17:21)


8

19.07.2011, 17:12

-> ist die komfortablere Schreibweise für (*objekt).methode(); bzw. (*objekt).var;

Mit dem Pfeiloperator kannst du somit auf die Member jenes Objekts einer Klasse zugreifen auf welches der Zeiger zeigt,
d.h. du deferenzierst den Zeiger, und kannst, ohne den . Operator, auf die Member der jeweiligen Klasse zugreifen..
Ich hoffe es war verständlich :),

Erebos

Edit: NachoMan war schneller :/

9

19.07.2011, 17:16

Ah, ok.
Dann macht das Sinn, Danke :D .

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

19.07.2011, 17:17

p_SpielerRaumschiff ist ein Zeiger auf ein Objekt der Klasse C_Raumschiff. Der Zeiger kann nicht auf ein Objekt der Klasse C_Jaeger zeigen, auch nicht wenn diese Klasse von C_Raumschiff erbt.

Quellcode Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
class C_Raumschiff     // Basis-Klasse für ein Raumschiff
{};

class C_Jaeger : public C_Raumschiff     //  Diese Klasse erbt die Member von C_Raumschiff
{};

C_Raumschiff* pNeuesRaumschiff;
pNeuesRaumschiff = new C_Jaeger;   // Das hier funktioniert nicht! Ein Zeiger für C_Raumschiff kann nicht auf C_Jaeger zeigen.


Vielleicht verdeutlicht das noch mal wie du in deinem Fall mit Klassen, Zeigern und Vererbung umgehen musst.

Oder es verdeutlicht, dass Du beim Thema Polymorphie geschlafen hast. Das geht nämlich ganz prima.
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