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

TigerClaw25

unregistriert

1

02.04.2013, 18:40

Das geheimnis der Zeiger

hallo,
kurze frage zum Thema Zeiger.

funktion: void cKlasse::MontiereTank(cTank *pZeiger)

warum wird im buch in der main lediglich das Objekt uebergeben, also ohne &-Operator? dachte, es sollte fuer Zuweisungen immer der &Operator verwendet werden. verstehe das nicht ganz.

FSA

Community-Fossil

  • Private Nachricht senden

2

02.04.2013, 18:57

Vielleicht wurde dein Objekt so im Quellcode geschrieben:

C-/C++-Quelltext

1
cTank* pTank;

Dann muss man keine Referenz mehr übergeben.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

3

02.04.2013, 19:15

Geiler Titel. So wird später mal mein erstes Buch heißen.
Danach dann: Die Kammer der Referenzen und der Stein der smart pointer.

Zum Thema: Etwas mehr Code wäre hilfreich, sonst wissen wir ja nicht, wie FSA ja schon meint, was da genau vonstatten geht.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

TigerClaw25

unregistriert

4

02.04.2013, 20:57

Zum einen gehe ich im Forum zum Buch davon aus, dass die anderen das Buch auch besitzen und zum anderen steht im Buch definitiv:
cTank *pTank; und nicht cTank* pTank;

Hier mal der gesamte Code:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// C++ für Spieleprogrammierer
// Listing 4.12
// Friend-Klassen
//
#include <iostream>

using namespace std;

// Klassen
//

// Klasse für den Tank eines Raumschiffs
//
class CTank
{
    // Die Klasse CAntrieb hat Zugriffsrechte auf
    // die privaten Klassenelemente
    friend class CAntrieb;

    public:
        CTank  (int MaxTreibstoff);
        ~CTank ();

    private:
        int m_Treibstoffmenge;

};

// Konstruktor
//
CTank::CTank (int MaxTreibstoff)
{
    cout << "Neue Tank-Instanz erstellt" << endl;

    // Treibstoffmenge festlegen
    m_Treibstoffmenge = MaxTreibstoff;

} // Konstruktor

// Destruktor
//
CTank::~CTank ()
{
    cout << "Tank-Instanz freigegeben" << endl;

}


// Klasse für einen Antrieb
//
class CAntrieb
{
    public:
        CAntrieb (int Verbrauch);
        ~CAntrieb ();
        void MontiereTank (CTank *pTank);
        void Schub ();

    private:
        CTank *m_pTank;
        int    m_Verbrauch;

};

// Konstruktor
//
CAntrieb::CAntrieb (int Verbrauch)
{
    cout << "Neuer Antrieb erstellt" << endl;

    // Verbrauch festlegen
    m_Verbrauch = Verbrauch;

} // Konstruktor

// Destruktor
//
CAntrieb::~CAntrieb ()
{
    // Montierten Tank entfernen
    if (m_pTank != NULL)
    {
        delete (m_pTank);
        m_pTank = NULL;
    }

    cout << "Antrieb freigegeben" << endl;

} // Destruktor

// MontiereTank
//
void CAntrieb::MontiereTank (CTank *pTank)
{
    // Zeiger auf übergebenen Tank kopieren
    m_pTank = pTank;

    cout << "Tank montiert" << endl;

} // MontiereTank

// Schub
//
void CAntrieb::Schub ()
{
    // Reicht der verbleibende Treibstoff noch?
    if (m_pTank->m_Treibstoffmenge - m_Verbrauch < 0)
    {
        // Nein, also kein Schub mehr möglich
        cout << "Tank ist leer!" << endl;
    }
    else
    {
        // Der Treibstoff reicht noch, also Menge abziehen
        cout << "Antrieb gibt Schub" << endl;
        m_pTank->m_Treibstoffmenge -= m_Verbrauch;
    }

} // Schub

// Hauptprogramm
//
int main ()
{
    // Instanzen für Tank und Antrieb
    CAntrieb *pAntrieb;
    CTank    *pTank;

    // Neuen Tank mit 170 Einheiten Treibstoff erstellen
    pTank = new CTank (170);

    // Neuen Antrieb mit Verbrauch von 35 Einheiten
    // Treibstoff erstellen
    pAntrieb = new CAntrieb (35);

    // Den Tank an den Antrieb montieren
    pAntrieb->MontiereTank (pTank);


    // Antrieb gibt mehrmals Schub
    for (int i=0; i<5; i++)
    {
        pAntrieb->Schub ();
    }

    // Antrieb freigeben. Die Tank-Instanz muss (darf)
    // nicht freigegeben werden, da dies im Destruktor
    // der Antriebsklasse geschieht
    //
    if (pAntrieb != NULL)
    {
        delete (pAntrieb);
        pAntrieb = NULL;
    }

    return (0);
}

Sp3iky

Treue Seele

Beiträge: 232

Beruf: Entwicklungsingenieur

  • Private Nachricht senden

5

02.04.2013, 22:01

cTank *pTank; und cTank* pTank; ist programmtechnisch exakt das selbe, ein Pointer auf ein Objekt vom Typ cTank.

Genauso wird in der Funktion ein Pointer auf ein Obejekt vom Typ cTank erwartet. Mir ist die Schreibweise cTank* pTank auch lieber, da ich sie eindeutiger finde, aber ich kann dir nicht sagen, welche Version diejenige ist, die in den meisten Konventionen verwendet wird und warum das so ist.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

03.04.2013, 06:37

Tja, das liegt daran:
cTank* p1, p2;
Hier ist p2 kein Pointer, obwohl man es auf den ersten Blick vermuten könnte.
Daher ist
cTank *p1, *p2;
eindeutiger.
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]

TigerClaw25

unregistriert

7

03.04.2013, 07:45

Verstehe jetzt trotzdem nicht, warum das Objekt an MontiereTank uebergeben wird und nicht die Adresse, so wie es bei Funktionen und Paarameteruebergabe auch immer der Fall war, siehe meine Frage oben ...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

03.04.2013, 07:53

Weil die Variable schon ein Zeiger IST. Sonst würdest Du ja einen cTank** übergeben (Adresse eines Pointers, bzw. Pointer auf einen Pointer). Das ist natürlich Quatsch.

Ist int i, dann ist &i ein int*.
Ist int* i, dann ist &i ein int**.
Ist int* i, dann ist *i ein int.
Ist int** i, dann ist *i ein int* und **i ein int.
Das lässt sich nun beliebig fortsetzen.
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 1 mal editiert, zuletzt von »BlueCobold« (03.04.2013, 08:00)


TigerClaw25

unregistriert

9

03.04.2013, 12:17

Stimmt, ich uebergebe ja nicht rekt eine Instanz, sondern bereits einen Zeiger.
Ich koennte doch dann auch das Objekt për & Operator uebergeben, muesste dann aber im Funktionskopf einen Zeiger auf den Zeiger angeben, also cKlass **Tank

10

03.04.2013, 12:33

Ich koennte doch dann auch das Objekt për & Operator uebergeben, muesste dann aber im Funktionskopf einen Zeiger auf den Zeiger angeben, also cKlass **Tank

Würde allerdings relativ wenig Sinn machen.

Werbeanzeige