PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : pointer auf klassen/strukturen


amida maru
2007-02-19, 16:29:15
Tach. Also ich hab mal wieder ein Problem. ich kapier nicht wieso man pointer auf strukturen und klassen braucht. zum beispiel HGE *hge = 0;
Ich hab gedacht pointer brauch man nur um lokale variablen "global" zu machen also überall im programm benutzen können....
bitte erklärt mir dieses thema.


mfg
amidamaru

Monger
2007-02-19, 16:41:22
Blöde Frage, aber von was für einer Sprache redest du überhaupt? C++?

Gast
2007-02-19, 16:54:21
So viel zum Thema RPG programmieren :D Sorry, das konnte ich mir jetzt grad nicht verkneifen ;)

Ansonsten: Variablen global machen? Bloß nicht! Abgesehen davon sind Klassen letztlich auch nur Variablen (die dann Objekte heißen...)...

amida maru
2007-02-19, 17:21:50
hmm ja c++....kann jetzt wer mir das erklären? wäre nett...
danke

bye

Monger
2007-02-19, 17:32:49
Erstmal ist die Unterscheidung wichtig: Klasse != Objekt. Du hast hier einen Pointer auf ein Objekt, und der hat nunmal irgendeine Nummer im Speicher. Dass du den auf Null setzst, ist bestimmt nicht sinnvoll.

Dein Pointer sagt dir also, wo du im Speicher nach deinem Objekt suchen musst, wenn du damit irgendwas anstellen willst. Und statt das ganze Objekt an eine andere Methode zu übergeben (was im Endeffekt dazu führt, dass eine lokale Kopie des Objekts erzeugt wird), übergibt man nur den Pointer, und ermöglicht so einer fremden Methode auf dem selben Objekt zu arbeiten.

Das ist eine Spezialität von C/C++ , darüber sollte man sich klar sein. Andere Sprachen kennen überhaupt keine Pointer.

Silpion
2007-02-19, 17:38:45
Hier steht's ausführlichst:
http://www.cplusplus.com/doc/tutorial/pointers.html

Gebraucht wird es überall, wo du einer Funktion nicht sagen willst "da, nimm diese Zahl", sondern "da drüben hab ich meine Daten, mach was damit und änder sie ggf.".
void foo(int i) // foo bekommt eine Kopie von i
{
i += 5; // Erhöht die Kopie um 5
} // Kopie wird gelöscht
=> foo hat keinen Effekt

void bar(int* i) // Bar bekommt eine Kopie des Zeigers auf i
{
*i += 5; // Erhöht die Zahl, auf die der Zeiger zeigt um 5
} // Die Kopie des Zeigers wird gelöscht
=> bar hat die Zahl erhöht. Die Kopie des Zeigers wird zwar gelöscht, aber du kannst an anderen Stellen im Programm noch Zeiger auf die Zahl haben, die nun erhöht wurde.

Gast
2007-02-19, 18:41:31
Erstmal ist die Unterscheidung wichtig: Klasse != Objekt. Du hast hier einen Pointer auf ein Objekt, und der hat nunmal irgendeine Nummer im Speicher. Dass du den auf Null setzst, ist bestimmt nicht sinnvoll.es sei denn, es ist grad noch kein Objekt da auf das er zeigen könnte.

Dein Pointer sagt dir also, wo du im Speicher nach deinem Objekt suchen musst, wenn du damit irgendwas anstellen willst. Und statt das ganze Objekt an eine andere Methode zu übergeben (was im Endeffekt dazu führt, dass eine lokale Kopie des Objekts erzeugt wird), übergibt man nur den Pointer, und ermöglicht so einer fremden Methode auf dem selben Objekt zu arbeiten.

Das ist eine Spezialität von C/C++ , darüber sollte man sich klar sein. Andere Sprachen kennen überhaupt keine Pointer.jedenfalls nicht offiziell :D
In Java oder C# z.B. sind Objektbezeichner de facto immer Pointer, auch wenn die Verfechter dieser Sprachen es gerne vermeiden das so auszudrücken und nicht müde werden voll glühendem Eifer zu beteuern, es handele sich um etwas völlig anderes als um Pointer. In Java spricht man stattdessen von Referenzen oder Verweisen.
Übergibt man z.B. in Java einer Methode einen Objektbezeichner als Parameter, so erhält die Methode mitnichten eine Objektkopie (wie das in C++ der Fall wäre), sondern nur eine Kopie der Objektreferenz (also des nur nicht so genannten Pointers) - das Objekt auf das diese zeigt ist dasselbe. So wie wenn man in C++ einen Pointer auf das Objekt übergeben würde.
Zugegeben, man kann mit den Referenzen in Java nicht all den Schabernack treiben wie in C++ mit Pointern. An der Eigenschaft, de facto Pointer zu sein, ändert das aber gar nichts.

Die Spezialität von C++ gegenüber Java oder C# ist also weniger, daß es Pointer gibt. Sondern eher das Gegenteil: nämlich daß man in C++ mit Objekten auch direkt hantieren kann, ohne Umweg über Pointer.

Gast
2007-02-19, 18:50:09
um das mal an einem Beispiel klar zu machen:
in C++ gibt es zwei Möglichkeiten

// Funktion bekommt Objekt als Parameter
void doAction1(Klasse objekt)
{
//...
}

// Funktion bekommt Pointer auf Objekt
void doAction2(Klasse *pobjekt)
{
//...
}

die Java-Lösung:

void doAction(Klasse objekt)
{
//...
}

entspricht C++ Lösung Nr. 2. Eine Entsprechung zu Lösung Nr. 1 gibt es in Java nicht.

amida maru
2007-02-19, 19:08:13
naja ok danke pointer kapier ich ja aber pointer auf strukturen nicht....

Kinman
2007-02-19, 19:37:21
Gehn wir mal von einem Spiel aus.

Du hast eine Struktur erzeugt, die irgendwelche Statistiken beinhaltet und eventuell auch recht groß ist. Jetzt hast Du eine Funktion, die etwas an der Statistik ändert.

2 Möglichkeiten:
Die Struktur der Funktion übergeben (also Struktur kopieren -> braucht mehr Speicher) die Daten in der Struktur ändern und dann die Struktur zurückgeben und die alte Struktur mit der Zurückgegebenen wieder überspeichern -> wieder kopieren.

Oder Du übergibst die Referenz der Struktur der Funktion und änderst die originale Struktur direkt in der Funktion.

Rate mal was sinnvoller ist...

mfg Kinman

Xmas
2007-02-19, 21:43:19
um das mal an einem Beispiel klar zu machen:
in C++ gibt es zwei Möglichkeiten
Es gibt noch eine dritte Möglichkeit, und diese entspricht am ehesten den Java-Referenzen. Allerdings sind C++-Referenzen nicht nullbar.

// Funktion bekommt Referenz als Parameter
void doAction3(Klasse& objekt)
{
//...
}

amida maru
2007-02-19, 21:57:06
Kinman ein beispiel wäre nett....

Kinman
2007-02-19, 23:08:01
Kinman ein beispiel wäre nett....

Hmm.. ich weiß jetz nicht mehr obs stimmt, hab schon ewig nix mehr mit c++ gmacht, aber ich versuchs ;)


//Funktion
Point addSome1(Point p)
{
p.x += 1;
p.y += 1;
return p;
}

void addSome2(Point &p)
{
*p.x += 1;
*p.y += 1;
}

//Main
struct Point
{
int x;
int y;
};

Point p1;
p1.x = 1;
p1.y = 2;

//Methode 1 -> langsam
p1 = addSome(p1);

//Methode 2 -> schneller
addSome2(p1);


Aber wie gesagt, keinen Anspruch auf Korrektheit ;)

ShadowXX
2007-02-19, 23:14:16
Kinman ein beispiel wäre nett....


struct hallo
{
int a;
double b;
bool c;
};

void main()
{
hallo daten;
daten.a = 1;
daten.b = 2.76;
daten.c = true;

machwas(&daten);

// hier kann man jetzt was mit den veränderten daten machen, z.B. Ausgeben
}

void machwas(hallo *value)
{
value->a += 1;
value->b -= 1.66;

if(value->c)
value->c = false;
else
value->c = true;
}


Das Beispiel ist zwar etwas sinnbefreit, da ich die Übergabe normalerweise als Referenz gemacht hätte.....aber es ging ja nur darum zu zeigen, was man mit einem Pointer auf eine Struktur machen könnte (bzw. wie das ganze aussieht).

Es ist im Prinzip das gleiche wie mit der Übergabe eines Pointers einer einzelnen Variable.

Der Vorteil wurde schon angesprochen: Platzsparender und (wesentlich) schneller (speziell bei großen Strukturen, Klassen oder strings), da man nur den Zeiger auf die Datenstruktur übergibt und nicht extra eine Kopie anfertigt.

Man trifft das ganze auch häufig als Rückgabe von Betriebssystemfunktionen an.

Das ist natürlich nur die Spitze des Eisbergs....mit Pointern kann man ziemlich viele gemeine und haarsträubende Sachen machen (und auch ziemlich viel falsch machen).

Interessant werden dann Pointer auf Pointer;)

Xmas
2007-02-19, 23:57:11
Eines der verständlichsten Beispiele für Pointer auf Strukturen dürfte wohl eine verkettete Liste sein, in der jedes Element einen Pointer auf den Nachfolger beinhaltet.

Monger
2007-02-20, 08:36:55
jedenfalls nicht offiziell :D
In Java oder C# z.B. sind Objektbezeichner de facto immer Pointer, auch wenn die Verfechter dieser Sprachen es gerne vermeiden das so auszudrücken und nicht müde werden voll glühendem Eifer zu beteuern, es handele sich um etwas völlig anderes als um Pointer. In Java spricht man stattdessen von Referenzen oder Verweisen.

Argh... Schmerzen...ich...muss...widersprechen... :D

Natürlich basiert alles im Endeffekt auf indirekter Adressierung. Aber ein Pointer zeigt irgendwo in den Arbeitsspeicher hinein, sagt also direkt etwas über die physikalische Speicherstruktur des Rechners aus. Deshalb kann man mit Pointern auch so Späße machen wie z.B. einen Offset hinzuzurechnen, und programmfremde Daten überschreiben.

In Java oder C# ist eine Referenz eine Objektnummer, mit der man auf dem Objekt Stack etwas wiederfinden kann. Wie das ganze hintendran im Speicher abgebildet wird, ist gar nicht erkennbar, und auch völlig unwichtig.

Indirekte Adressierung ist selbstverständlich im Endeffekt das A und O womit der Rechner arbeitet. Aber "Pointer" ist typische C++ Terminologie (und natürlich noch von ein paar anderen Sprachen), und die C++ Entwickler sollen nicht so tun, als wäre das ein Grundelement aller Sprachen! ;)

amida maru
2007-02-20, 10:46:40
gute beispiele danke aber wenn ich zum beispiel sowas hab wie in shadows beispiel if(value.c) heisst das dann wenn value.c true ist dann mach das und das?

ShadowXX
2007-02-20, 11:01:49
gute beispiele danke aber wenn ich zum beispiel sowas hab wie in shadows beispiel if(value.c) heisst das dann wenn value.c true ist dann mach das und das?
Ja, genau das heißt das...(wobei mir da ein kleiner Fehler bei meinem Code aufgefallen ist, es hätte if(value->c) heißen müssen, habs oben schon verbesssert).

Bei "if", "while", "for" & Co. reicht es bei C/C++ aus, wenn der zu überprüfende Wert wahr ist, damit eingesprungen bzw. fortgefahren wird (und vice versa).

D.h. if(value->c) ist genau das gleiche wie if(value->c == true)....und sehr wahrscheinlich wird der Compiler aus beidem auch genau den gleichen Code erzeugen.

Du solltest aber immer daran denken das alles, was nicht "0" ist "true" ist. Es können dir also durchaus auch Konstrukte über den Weg laufen wie:

.....
int c = a + b;
if(c)
{
// irgendwelcher code
}
else
{
// irgendwelcher code
}
....

oder

....
int a = 5;
int b = 0;
while(a - b)
{
b++;
// irgendwelche code
}
...

oder

....
int a = 0;
int b = 5;
for(a = 0; b - a; a++)
{
// abzuarbeitender code
}
...

Häufig wird auch die Gültigkeit von Pointern und Handles mit ifs abgefragt (da ein Null-Pointer ebenfalls "false" ist, denn er ist ja "0").

P.S.
nur noch mal als Anmerkung....die Beispielcodes sollen nur die Funktionsweise verdeutlichen und es ist nicht unbedingt sinnvoll schleifen auf diese art und weise zu bauen.

amida maru
2007-02-20, 20:17:26
also shadow bei deinem zweiten beispiel mit while(a-c) wird geprüft ob a - c 0 ist? und wenn a - c 0 ist dann ist es false und wenns irgendein andern wert über 0 oder unter 0 ist dann wirds ausgeführt?

ShadowXX
2007-02-21, 23:27:41
also shadow bei deinem zweiten beispiel mit while(a-c) wird geprüft ob a - c 0 ist? und wenn a - c 0 ist dann ist es false und wenns irgendein andern wert über 0 oder unter 0 ist dann wirds ausgeführt?
Ja....alles was nicht 0 ist ist true und 0 ist äquivalent zu false.

tokugawa
2007-02-22, 00:12:44
Erstmal ist die Unterscheidung wichtig: Klasse != Objekt. Du hast hier einen Pointer auf ein Objekt, und der hat nunmal irgendeine Nummer im Speicher. Dass du den auf Null setzst, ist bestimmt nicht sinnvoll.

Dein Pointer sagt dir also, wo du im Speicher nach deinem Objekt suchen musst, wenn du damit irgendwas anstellen willst. Und statt das ganze Objekt an eine andere Methode zu übergeben (was im Endeffekt dazu führt, dass eine lokale Kopie des Objekts erzeugt wird), übergibt man nur den Pointer, und ermöglicht so einer fremden Methode auf dem selben Objekt zu arbeiten.

Das ist eine Spezialität von C/C++ , darüber sollte man sich klar sein. Andere Sprachen kennen überhaupt keine Pointer.

Um es etwas zu exaktifizieren: Was du hier als "Objekt" bezeichnest, ist eine sogenannte Klasseninstanz. Laut "klassischem" OO-Modell (was nicht mal direkt aus der Programmierung kommt) gibt es durchaus die Terminologie dass sowohl Klassen als auch Instanzen "Objekte" sind.

Weiters muß man exaktifizieren (weil dein letzter Satz dies nicht eindeutig sagt), dass Pointer keine Spezialität von C/C++ sind, sondern auch in Sprachen wie Pascal vorkommen. Die "Spezialität", die C/C++ mit Pointern beherrscht, ist dass C/C++ sehr freizügig in Bezug auf Pointer-Arithmetik ist, was historisch daraus bedingt ist, dass C als "portabler Assembler" konzipiert wurde, und Pointer sind ja ein Konzept das auf Assembler-Ebene immer vorkommt.

Gast
2007-02-24, 20:41:28
also shadow bei deinem zweiten beispiel mit while(a-c) wird geprüft ob a - c 0 ist? und wenn a - c 0 ist dann ist es false und wenns irgendein andern wert über 0 oder unter 0 ist dann wirds ausgeführt?
Was du in die Klammer bei if() oder while() reinschreibst ist eine boolean expression, und das kann eben auch was komplizierteres sein, solange es der Compiler entsprechend auswerten kann gibts keine Probleme. Hierbei kanns natürlich sein dass implizit konvertiert wird, deshalb funktionieren Sachen wie

int a,b,c;
if (a+b*c) // ist dasselbe wie if(a+b*c != 0)
//tu was
boolean expression heißt ja im Prinzip nix was anderes als dass der Ausdruck zu einer Zahl auswertbar ist, wenn die dann gleich 0 ist ->leider nein, ansonsten juhu.

Nicht funktioniert z.B:

std::string x="bla";
if(x)
//tu was

Hier kann der Compiler nicht von string nach bool konvertieren und wird sich aufregen.