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

06.03.2007, 16:25

Instanzieren oder einen Pointer setzen?

Hallo Zusammen!

Wann sollte ich eine Klasse/Struktur instanzieren und wann sollte ich einen Pointer drauf setzen?

Mfg
Sprachen: C/C++, C#, Assembler (16-Bit), QuickBASIC

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

06.03.2007, 16:45

Hä? Worauf willst du einen Pointer setzen, wenn du keine Instanz hast?

3

06.03.2007, 17:06

Ich hab mal gelesen, dass du Allegro kannst, von da her folgendes Beispiel:

Also es gibt da ne Klasse BITMAP und ich setze immer einen Pointer auf BITMAP. Aber ich Instanziere BITMAP nie, warum?

C-/C++-Quelltext

1
2
3
4
5
6
7
8
#include <allegro.h>

int main()
{
   allegro_init();
   BITMAP *IrgendeinBild = ...
   ...
}


Warum instanziert man im folgenden Fall nicht einfach BITMAP?
Sprachen: C/C++, C#, Assembler (16-Bit), QuickBASIC

riCo

Treue Seele

Beiträge: 165

Beruf: Student

  • Private Nachricht senden

4

06.03.2007, 17:06

Re: Instanzieren oder einen Pointer setzen?

Zitat von »"Reboot"«

Hallo Zusammen!
Wann sollte ich eine Klasse/Struktur instanzieren und wann sollte ich einen Pointer drauf setzen?


Die Instanz ist das Objekt der Klasse/Struktur. Jetzt les dir deinen Satz nochmal in ruhe durch..
Wir leben alle unter dem Sternenhimmel, aber wir haben nicht alle den gleichen Horizont.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

06.03.2007, 17:07

weil das vermutlich die funktion, die nach dem = kommt für dich macht.

riCo

Treue Seele

Beiträge: 165

Beruf: Student

  • Private Nachricht senden

6

06.03.2007, 17:08

Interessant wäre, was nach dem "=" kommt..

EDIT
------

Das hast du bei Java oder dem .NET-Framework oft, dass dir ne Klasse ein Objekt für eine andere Klasse übergibt und du diese nicht automatisch anlegen kannst. Beispielsweise bei Singleton, kommt halt auf die Implementierung an..
Wir leben alle unter dem Sternenhimmel, aber wir haben nicht alle den gleichen Horizont.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

06.03.2007, 17:09

ich tippe auf irgendwas in richtung LoadBitmap...

8

06.03.2007, 17:12

Zitat von »"dot"«

ich tippe auf irgendwas in richtung LoadBitmap...


Jo!

Und tschuldigung für die Dumme Frage: Hat mich halt nur interressiert, warum man in diesem fall einen Pointer auf eine Klasse setzt und nicht zuerst eine Instanz erstellt.
Sprachen: C/C++, C#, Assembler (16-Bit), QuickBASIC

helium

Treue Seele

Beiträge: 180

Wohnort: NRW, Burscheid (nahe Köln)

  • Private Nachricht senden

9

07.03.2007, 15:12

Ein Pointer/Zeiger ist ein Verweis irgendwo hin. Er kann nur auf schon existierende Objekte zeigen. Instanz ist hier lediglich ein anderes Wort für Objekt.

Man kann Objekte/Instanzen entweder lokal erzeugen (das landet dann auf dem Stack) oder eben dynamisch (das landet dann auf dem Heap). Nehmen wir an es gäbe die Klasse Foo.

Statische Instanzierung sieht so aus:

C-/C++-Quelltext

1
2
3
{
   Foo objekt;  // hier wird lokal ein Objekt angelegt.

}


Um nochmal zu verdeutlich, was ein Zeiger ist:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
{
   Foo objekt1;
   Foo objekt2;
  
   Foo * verweis = &objekt1;  // "verweis" zeigt nun auf objekt1. 


   verweis->irgendwas(); // irgendas wird auf objekt1 aufgerufen



   verweis = objekt2;
   verweis->irgendwas(); // irgendas wird jetzt auf objekt2 aufgerufen

}


Man kann Objekte auch dynamisch anlegen:

C-/C++-Quelltext

1
2
3
4
{
   Foo * verweis = new Foo();  // hier wird dynamisch ein Objekt angelegt.

   ...
}

new Foo() legt irgendwo ein Objekt an, also eine Instanz des Typs Foo. Das Objekt ist im Grunde nicht anders, als die Objekte, die wir oben angelegt haben. Es hat nur keinen direkten Namen, unter dem wir es ansprechen können. Wir haben "nur" einen Zeiger darauf. Geht uns das Objekt verloren, z.B. wen wir "verweis" einfach auf was anderes Zeigen lassen. Das Objekt ansich existiert noch irgendwo, aber wir kämen nciht mehr dran.

Außerdem müssen wir dynamisch angelegte Objekte selbst auch wieder beseitigen, indem wir delete verwenden.

-------

Nun kann ich folgendes machen: Ich baue eine Funktion, die ein Objekt anlegt, und gebe dann einen Verweis auf dieses Objekt zurück:

C-/C++-Quelltext

1
2
3
4
5
Foo * erzeugeEinFoo ()
{
   Foo * temp = new Foo();
   return temp;
}


Geht natürlich kürzer. der Zeiger "temp" ist im Grunde überflüssig. Wir wollen ja einfach nur das von new erzeugte Objekt zurückgeben. Aber vielen fällt es einfacher das ganze zu verstehen, wenn man auch die gerae gezeigte längere Version einmal vorführt.

C-/C++-Quelltext

1
2
3
4
Foo * erzeugeEinFoo ()
{
   return new Foo();
}


So. Anwenden können wir das ganze jetzt so:

C-/C++-Quelltext

1
2
3
4
{
   Foo * verweis = erzeugeEinFoo();
   ...
}

"erzeugeEinFoo" erzeugt jetzt ein Foo-Objekt und wir bekommen einen Zeiger darauf, den wir in "verweis" speichern. Dann können wir wie gewohnt mit dem Objekt arbeiten.

Warum machen wir das ganze. Warum erzeugen wir dynamisch ein Objekt in "erzeugeEinFoo"? Warum geben wir nicht direkt ein Objekt wieder, sondern nur einen Verweis?
Tja, einfach mal durchspielen:

C-/C++-Quelltext

1
2
3
4
5
Foo erzeugeEinFoo2 ()
{
   Foo temp;
   return temp;
}


Und in kurz:

C-/C++-Quelltext

1
2
3
4
Foo erzeugeEinFoo2 ()
{
   return Foo();
}


Vergleichen wir beide Funktionen mal:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
{
   Foo objekt;   // (1)

   Foo *verweis;  // (2)


   objekt = erzeugeEinFoo2();  // (3)

   verweis = erzeugeEinFoo();  // (4)

   ...
}


Bei (1) wird direkt schon ein Objekt angelegt, bei (2) hingegen nicht. Es existiert nur ein nicht initialisierter Zeiger (also einen, den wir noch nciht benutzen können).

Bei (3) Wird nun von erzeugeEinFoo2() ein Objekt erzeugt und dieses wird dann in das bereits vorhandene Objekt namens "objekt" kopiert. Nehmen wir mal an, das es sich bei Foo um eine Klasse handelt, die Bilder speichert, die auch ein paar MB groß sein können, dann könnten hier gerade mal eben ein paar MB kopiert worden sein.
Bei (4) wird einfach "verweis" auf das von "erzeugeEinFoo" erzeugte Objekt gesetzt. Egal, wie groß oder klein das eigentliche Objekt ist, das ganze geht blitz schnell. Das eigentliche Objekt wurde ja gar nciht angefasst.

Natürlich sind meine Beispielfunktionen etwas sinnlos, weil sie einfach new mit einem bestimmte Typen, bzw. einfach nur einen Konstruktoraufruf ersetzen.


Um mal konkreter auf dein Beispiel einzugehen:

C-/C++-Quelltext

1
BITMAP *irgendeinBild = LoadBitmap (...);


LoadBitmap erzeugt ein Objekt. Dieses Objekt speichert jetzt ein Bitmap. Das Objekt ist jetzt also schon erzeugt und vermutlich recht groß (wie es bei Bitmaps nunmal so ist). Wozu sollten wir jetzt selbst nochmal ein Objet erzeugen und das bereits erzeugte Bitmap da reinkopieren? Das wäre ja unnötiger Aufwand. Außerdem hätten wir zweimal die selben Daten gespeichert. Wäre natürlich Quatsch. Also setzten wir einfah einen Zeiger auf das bereits durch LoadBitmap erzeugte Objekt.

Ich hoffe ich konnte einiger Maßen helfen.
Why is 6 afraid of 7?
Because 7 8 9

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

10

07.03.2007, 15:33

Zitat von »"helium"«

aus:

C-/C++-Quelltext

1
2
3
4
   Foo objekt1;
   Foo objekt2;
  
   Foo * verweis = objekt1;  // "verweis" zeigt nun auf objekt1.


Bitte was ? Schon mal das Zeichen & gesehen ??
Foo &ref = objekt1;
oder
Foo *pnt = &objekt1;

Bitte pass auf wenn du was erklaerst!
"Have you tried turning it off and on again?"

Werbeanzeige