Forum: PC-Programmierung Zeiger innerhalb einer Klasse - Zugriff?


von Frank (Gast)


Lesenswert?

Guten Morgen,
kann mir jemand sagen, ob es möglich ist, Zeiger innerhalb einer Klasse 
zu deklarieren und darauf dann über eine Klassen Instanz auf dem Stack 
zuzugreifen?

Beispiel:
1
class CSpieler 
2
{
3
  public:
4
  int *ptr;
5
};
6
7
// Hauptprogramm
8
//
9
int main ()
10
{
11
  CSpieler Spieler1;
12
  Spieler1.ptr = 50;
13
  
14
  system ("Pause");
15
  return 0;
16
}

Das Beispiel funktioniert so aber nicht. Oder ist es erforderlich mit 
new eine neue Instanz zu erstellen?

von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

Ohne deine genaue Absicht zu erkennen, möchtest du sowas?
1
*(Spieler1.ptr) = 50;

Oder sowas?
1
Spieler1.ptr = (int*)50;

: Bearbeitet durch User
von Frank (Gast)


Lesenswert?

Ich habe meine Fehler gefunden. Mein Zeiger "ptr" zeigt auf keine 
Adresse und das, was ich versuche ist eine Zuweisung eines int-Wertes. 
Der Zeiger kann aber lediglich Adressen speichern.

Dennoch verstehe ich eine Sache nicht. Warum heißt es nicht 
"(Spieler1.(*ptr))"? Spieler1 ist doch eine Instanz auf dem Stack. Wäre 
Spieler1 auf dem Heap, würde ich z.B. wie folgt auf Member zugreifen: 
Spieler1->ptr oder *(Spieler1.ptr). Aber ich habe nur einen Zeiger als 
Member einer Klasse, die Klasse selbst aber kein zeiger. warum dennoch 
die selbe Schreibweise?

von ui (Gast)


Lesenswert?

Frank schrieb:
> Dennoch verstehe ich eine Sache nicht. Warum heißt es nicht
> "(Spieler1.(*ptr))"? Spieler1 ist doch eine Instanz auf dem Stack. Wäre
> Spieler1 auf dem Heap, würde ich z.B. wie folgt auf Member zugreifen:
> Spieler1->ptr oder *(Spieler1.ptr). Aber ich habe nur einen Zeiger als
> Member einer Klasse, die Klasse selbst aber kein zeiger. warum dennoch
> die selbe Schreibweise?

Es spielt eigentlich keine Rolle ob der Spieler auf dem Heap oder Stack 
ist (aus Sicht der Syntax). Wo er genau liegt gibt dir dein 
Betriebssystem. Du musst dich nur u.U. selbst darum kümmern.

von nicht"Gast" (Gast)


Lesenswert?

Hä?

viel verwirrendes Zeug, was du schreibst :)


Frank schrieb:
> Ich habe meine Fehler gefunden. Mein Zeiger "ptr" zeigt auf keine
> Adresse und das, was ich versuche ist eine Zuweisung eines int-Wertes.
> Der Zeiger kann aber lediglich Adressen speichern.

Du kannst ja im Konstruktor deinem Zeiger etwas Speicher mit new 
zuweisen.

Frank schrieb:
> wäre
> Spieler1 auf dem Heap, würde ich z.B. wie folgt auf Member zugreifen:
> Spieler1->ptr oder *(Spieler1.ptr).

Das erste ist richtig, das zweite nicht. Das müsste (*Spieler1).ptr 
heißen.


Zum Schluss. Spieler1.ptr gibt dir einen Zeiger auf einen int zurück, 
den du mit * dereferenzieren muss. Macht am Ende des Tages 
*Spieler1.ptr. Die Klammern sind unnötig, da '.' eine höhere prio 
genießt als '*'

von M.K. B. (mkbit)


Lesenswert?

Nachdem meine Vorgänger bereits ausführlich die Syntax erklärt haben, 
hier noch eine paar Punkte zum Design.
Mir fallen spontan drei Fälle ein, warum man etwas mit oder ohne Pointer 
in einer Klasse speichert.

1) Die Klasse soll Zugriff auf einen externen int haben.
1
class CSpieler 
2
{
3
  public:
4
  int *ptr;
5
};
6
7
int main ()
8
{
9
  int i = 50;
10
  CSpieler Spieler1;
11
  *Spieler1.ptr = &i;
12
}

1a) Wenn der Zeiger auf den externen Integer sich nie ändert und schon 
bei der Konstruktion feststeht, kann du auch eine Referenz nehmen (die 
kann dann auch kein null_ptr sein). Allerdings muss man diese im 
Konstruktor setzen.
1
class CSpieler 
2
{
3
  public:
4
  CSpieler(int &x) : n(x) {}
5
  int &n;
6
};
7
8
int main ()
9
{
10
  int i = 50;
11
  CSpieler Spieler1(i);
12
}

2) Die Klasse soll den Integer nur als Parameter haben. In diesem Fall 
kannst du den Wert direkt in einen Member kopieren. Vom Speicherplatz 
macht es beim int keinen Unterschied zum Pointer, allerdings ist der 
Pointerzugriff evtl. langsamer, weil beim Zugriff erst der Pointer aus 
der Klasse geladen werden muss und dann anhand dieser Adresse im 
Speicher der Wert des int.

3) Die Variante 2 ist nicht gewünscht, weil es statt dem int eine 
größere Datenstruktur ist, die nicht auf dem Stack liegen soll. Oder 
weil man die Lebenszeit der Struktur unabhängig von CSpieler 
kontrollieren möchte.
Ich verwende einen unique_ptr, damit der Speicher in jedem Fall wieder 
freigegeben wird. Sonst könnte man vergessen im Destruktor den Speicher 
für den int wieder freizugeben.
1
class CSpieler 
2
{
3
  public:
4
  CSpieler() : ptr(new int) // Speicher für den int anlegen.
5
  std::unique_ptr<int> ptr;
6
};
7
8
int main ()
9
{
10
  int i = 50;
11
  CSpieler Spieler1;
12
  *Spieler1.ptr = &i;
13
}

von Rolf M. (rmagnus)


Lesenswert?

Frank schrieb:
> Ich habe meine Fehler gefunden. Mein Zeiger "ptr" zeigt auf keine
> Adresse und das, was ich versuche ist eine Zuweisung eines int-Wertes.
> Der Zeiger kann aber lediglich Adressen speichern.

Richtig.

> Dennoch verstehe ich eine Sache nicht. Warum heißt es nicht
> "(Spieler1.(*ptr))"? Spieler1 ist doch eine Instanz auf dem Stack. Wäre
> Spieler1 auf dem Heap, würde ich z.B. wie folgt auf Member zugreifen:
> Spieler1->ptr oder *(Spieler1.ptr).

Es ist vollkommen irrelevant, wo die Instanz liegt. Die Syntax hängt 
nicht davon ab, wo das Objekt liegt, auf das du zugreifst, sondern nur 
davon, wie  du darauf zugreifst.

> Aber ich habe nur einen Zeiger als Member einer Klasse, die Klasse selbst
> aber kein zeiger. warum dennoch die selbe Schreibweise?

Weil der Operator . stärker bindet als es * tut.
*Spieler1.ptr ist also das selbe wie *(Spieler1.ptr) und nicht wie 
(*Spieler1).ptr.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.