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

next

Frischling

  • »next« ist der Autor dieses Themas

Beiträge: 6

Beruf: Student

  • Private Nachricht senden

1

27.02.2014, 21:37

Problem mit Memberfunktion in Verbindung mit Zeiger

Hallo zusammen =)

Bin gerade dabei die Aufgabe aus dem Kapitel 7.8 zu bearbeiten.
Dafür wollte ich, wie auf den vorherigen Seitenim Buch, zunächst eine Klasse erzeugen und dann als Objekt einen Zeiger erstellen.
Anschließend soll damit eine Instanz auf dem Heap erzeugt werden.
Wenn ich nun aber die Memberfunktion Variablentest() (Zeile 51) aufrufen will und auf der linken Seite des Zuweisungsoperators der Zeiger steht, bekomme ich am Zeiger folgende Fehlermeldung:
"Der Ausdruck muss einen Klassentyp aufweisen".
Wenn ich als Operator den Pfeil "->" verwende, kommt die Fehlermeldung nicht.
Ich würde jetzt aber gerne mal wissen warum die Fehlermeldung überhaupt kommt, wenn das bei den vorherigen Beispielen doch so prima funktioniert hat.

Quelltext:

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
51
52
53
54
55
56
57
58
#include<iostream>

using namespace std;

class CRaumschiff
{

private:
    // Membervariablen
    int m_xPos;
    int m_yPos;
    int m_Energie;
    float m_fGeschwindigkeit;

public:
    // Memberfunktionen
    CRaumschiff(); // Konstruktor ohne Parameterliste wird aufgerufen
    CRaumschiff(int xPos, int yPos); // Konstruktor mit Parameterliste
    void Variablentest(int xPos, int yPos);
};

// Variablentest
// Aufgabe: Erkennen ob Raumschiff im Spielfeld ist oder nicht.
//
void CRaumschiff::Variablentest(int xPos, int yPos)
{
    if (0<= xPos <=800 && 0<= yPos <=600)
        cout<<"Koordinaten wurden gesetzt";
    else
    {
        cout<<"Koordinaten außerhalb des gueltigen Bereiches";
        m_xPos = 0;
        m_yPos = 0;
    }
}//Variablentest


main()
{
    //Variablen
    int xPos = 320; // x Position des Gegnerischen Raumschiffes
    int yPos = 610; // y Position des Gegnerischen Raumschiffes

    CRaumschiff *pSpieler = NULL; // Instanz erzeugen (als Pointer)
    CRaumschiff *pGegner = NULL; // Instanz erzeugen (als Pointer)

    // Speicher auf dem Heap reservieren,
    pSpieler = new CRaumschiff;
    pGegner = new CRaumschiff(xPos, yPos);

    pGegner.Variablentest(xPos, yPos); // Testen, ob der Gegner im Spielfeld ist
    
    // Speicher freigeben
    delete[] pGegner;
    pGegner= NULL;

    return 0;
}


Theoretisch bin ich so vorgegangen, wie das im Buch auch gemacht wird. Mit ausnahme der "[]" am Zeiger, denn mit denen würde es wieder funktionieren aber komme nicht drauf warum :S :hmm:

Danke für die Hilfe =) Gruß next

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

27.02.2014, 22:18

Zeile 51 ist syntaktisch einfach falsch. Wenn Du auf Member von einem Pointer-Typ zugreifen willst, musst Du den "->" Operator benutzen. Das ist eben so bei Zeigern. Übrigens ist der Pfeil da sicher nicht umsonst einem Zeiger so ähnlich...
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]

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

3

27.02.2014, 22:31

Es heißt int main().
Du gibst pSpieler nicht frei.
Warum verwendest du delete[] und nicht delete?

Dein Problem hat BlueCobold ja schon beantwortet. Du musst den zeiger derefferenzieren um auf das Objekt zugreifen zu können. Das machst du mit dem * Operator, also *pointer.method();. Als Kurzform gibt es halt den -> Operator, also pointer->method();.

Wenn du den Kram mit den Pointer verstanden hast, dann guck dir mal das hier an:
http://msdn.microsoft.com/de-de/library/hh279674.aspx

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

4

27.02.2014, 23:08


Das machst du mit dem * Operator, also *pointer.method();. Als Kurzform gibt es halt den -> Operator, also pointer->method();.

Es müsste (*pointer).method lauten, da der Punkt Operator stärker bindet.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

next

Frischling

  • »next« ist der Autor dieses Themas

Beiträge: 6

Beruf: Student

  • Private Nachricht senden

5

27.02.2014, 23:19

Erstmal vielen Dank für die schnellen Antworten =)

Ups das Int vor main() habe ich vergessen :P
Habe das auch schon gelesen, dass bei Pointern der Pfeil verwendet werden muss, jedoch nicht im Buch.
Und ich bin etwas verwirrt, was genau an dem Beispiel im Buch anders ist, weil da hat das funktioniert. (Zeile 19 und 29)
Hier mal ein kleiner Auszug:

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
 int main ()
 {
 // Variablen
 //
 CSpieler *pSpielerliste = NULL;
 int AnzahlSpieler = 0;

 // Anzahl der Spieler abfragen
 cout << "Wie viele Spieler: ";
 cin >> AnzahlSpieler;

 // Instanzen auf dem Heap erzeugen
 pSpielerliste = new CSpieler[AnzahlSpieler];

 // Namen aller Spieler abfragen
 for (int i=0; i<AnzahlSpieler; i++)
 {
 cout << "Spieler " << i+1 << endl;
 pSpielerliste[i].Init ();
 cout << endl;
 }

 // Liste der Spieler ausgeben
 cout << "Folgende Spieler sind mit von der Partie:" << endl;

 for (int j=0; j<AnzahlSpieler; j++)
 {
 cout << "Spieler " << j+1 << endl;
 pSpielerliste[j].ZeigeDaten ();
 }

 // Speicher freigeben
 delete[] pSpielerliste;
 pSpielerliste = NULL;

 return 0;
}

6

27.02.2014, 23:39

Im Gegensatz zu deinem vorherigen Code, hast du hier ein Array von CSpieler-Objekten, nicht einen Zeiger auf ein einzelnes Objekt. Deswegen wird in diesem Beispiel auch mit [] auf ein einzelnes Element zugegriffen (welches dann kein Zeiger ist) und somit ist der Memberzugriff über den "." Operator wieder zulässig. Dann ergibt auch die Verwendung von delete[] wieder Sinn.

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

7

28.02.2014, 10:12

Genau du hast ein Array von CSpieler Objekten. Man könnte so eins auch direkt über

Quellcode

1
CSpieler pSpielerListe[AnzahlSpieler];

anlegen, sofern AnzahlSpieler konstant ist (die größe eines Arrays muss zum Zeitpunkt es Übersetzens bekannt sein).

Um dynamisch zur Laufzeit ein Array zu erstellen benötigst du ein Pointer auf den Elementtypen und forderst den Speicher dann zur Laufzeit mittels new an. Dein Pointer zeigt dann quasi auf das erste Element des Arrays. Durch pSpielerliste bekommst du dann direkt das i-te Objekt (wirklich das Objekt, nicht nur einen Pointer darauf) zurück. Daher kannst du auch direkt mit dem . Operator darauf zugreifen. Die Notation mit [i] ist im Grunde nur eine Kurzform von (*(pointer+i)). Also du nimmst deinen Pointer auf das erste Element, gehst i Objekte weiter und derefferenzierst das Ganze dann.

Die alten C-Style Arrays werden natürlich in Lehrbüchern und Tutorials behandelt, aber sind in der Praxis meist nicht die optimale Wahl. Wenn du diese Kapitel durch und auch verstanden hast, dann guck dir doch mal std::array, std::vector und Smart Pointer an. Damit wirst du dir später das Leben leichter machen, als wenn es mit normalen Pointern und alten Arrays weiter geht.

next

Frischling

  • »next« ist der Autor dieses Themas

Beiträge: 6

Beruf: Student

  • Private Nachricht senden

8

28.02.2014, 17:31

Ok habs verstanden.
Das die Elemente des Arrays von dem Pointer angesprochen werden und damit das Objekt kein Zeiger ist sondern eben das Element hat mir gefehlt bzw. war ich mir nicht sicher =)
Jetzt kann ich wieder mit ruhigem Gewissen weiter machen hehe :P

Vielen Dank nochmal für die schnelle und sehr informative Hilfe

next

Werbeanzeige