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

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

1

09.11.2004, 13:27

manueller Konstruktoraufruf

ich bin gerade am überlegen, was besser ist:

C-/C++-Quelltext

1
CKlasse MeinExemplar; // automatischer Konstruktoraufruf


C-/C++-Quelltext

1
2
CKlasse* pMeinExemplar;
pMeinExemplar = new CKlasse; // manueller Aufruf


hat beides ab und zu seine vorteile. allerdings meine ich mal gehört zu haben, dass letzteres langsamer sei. wenn ja, warum?

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

09.11.2004, 14:08

Langsamer? Nicht das ich wüsste, aber das erste wird automatisch gelöscht, während das zweite mit einem delete aufruf gelöscht werden muss, was auch gewisse vorteile haben kann(Zeiger).

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

3

09.11.2004, 14:37

ich finde letzteres angenehemer. ich habe es irgendwo (weiß dummerweise nicht mehr wo) gelesen, dass die 2. methode langsamer sein soll. keine ahnung warum. mal angenommen, es wäre so, dann wäre der geschwindigkeitsunterschied ja sowieso sehr klein.

Patrick

Alter Hase

Beiträge: 1 264

Wohnort: Düren

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

4

09.11.2004, 14:41

also ich weiß jetzt zwar nicht was du mit automatisch oder manuell meinst, aber bei deinem 2. wird der constructor auch "automatisch" aufgerufen,

es sei denn du schreibst sowas:
vector *xzy = new vector (0,0,0);

Und was du schreibst ist auch schnuppe, nur eines: Speicherallokierung dauert mit new, drum wäre ein static ohne new schneller.

Anonymous

unregistriert

5

09.11.2004, 16:11

Manuellen Konstruktor-Aufruf gibt es nicht. Das, was am nächsten dran ist, wäre ein placement-new.

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

6

09.11.2004, 17:22

Zitat von »"Patrick"«

Und was du schreibst ist auch schnuppe, nur eines: Speicherallokierung dauert mit new, drum wäre ein static ohne new schneller.


was meinst du mit einem "static"?

Patrick

Alter Hase

Beiträge: 1 264

Wohnort: Düren

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

7

09.11.2004, 17:25

C-/C++-Quelltext

1
static meine_klasse test;

helium

Treue Seele

Beiträge: 180

Wohnort: NRW, Burscheid (nahe Köln)

  • Private Nachricht senden

8

12.11.2004, 16:56

OK, mal ein Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
{
   EineKlasse instanz;

   irgendNeFunktion();

   ... // mach was mit der 'instanz'

}


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
{
   EineKlasse * zeigerAufInstanz = new EineKlasse;

   irgendNeFunktion();

   ... // mach was mit der 'instanz'


   delete zeigerAufInstanz;
}



Scheinz gleichwertig, nur das die zweite Variante mehr Code umfast. Falsch gedacht. Der Aufruf von "irgendNeFunktion" ist ja nicht umsonst da.
Diese Funktion könnte ne Exception werfen. Die erste Variante hätte damit keine Probleme, bei der zweiten hätten wir mindestens ein Memory-Leak. Vielleicht bleiben auch Dateien offen oder sogar Datenbankanbindungen und was weiß ich nicht noch alles, nur weil das Objekt nicht ordnungsgemäß zerstört wurde.

Jetzt könnte man auf die Idee kommen einen try-Block um den Funktionsaufruf zu schreiben:


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
   EineKlasse * zeigerAufInstanz = new EineKlasse;
   
   try {
      irgendNeFunktion();
   }
   catch (...) {
      delete zeigerAufInstanz;
      throw;
   }

   ... // mach was mit der 'instanz'


   delete zeigerAufInstanz;
}


Aber jetzt stelle man sich mal vor, man würde nicht nur eine Funktion aufrufen sonderen mehrere und man würde in der Funktion nicht nur ein Objekt erstellen, sondern mehrere. Die Funktion würde gigantische Ausmaße annehmen.
Vor allem allein schon wegen sowas:

C-/C++-Quelltext

1
2
Foo * foo = new Foo;
Bar * bar = new Bar;


Sollte 'new Bar' eine std::bad_alloc werfen, wer würde dann das von 'foo' referenzierte Objekt freigeben?

Man sieht, das Variante ohne dynamisches Allokieren ganz klar zu bevorzugen ist.


P.S.
Die gezeigten Probleme könnte man auch mit Smart-Pointern umgehen.

MarkusS

Frischling

Beiträge: 3

Wohnort: Püttlingen

Beruf: Softwareentwickler

  • Private Nachricht senden

9

13.11.2004, 22:09

Die erste Variante ist klar vorzuziehen. Sie ist schneller und kostet weniger Speicher als die 2.

Bei Variante 1 wird das Objekt auf dem Stack angelegt, dies geht sehr schnell, da lediglich der Framepointer um die Größe des Objekts verschoben werden muss. Es werden auch keine weiteren Verwaltungsstrukturen angelegt.

Bei der 2. Variante muss der Heap nach einem ausreichend großen freien Bereich durchsucht werden, was je nach Auslastung und Fragmentierung des Heaps sehr lange dauern kann. Wurde ein entsprechender Bereich gefunden muss er zerteilt werden. In ein Teil kommt das neue Objekt, der andere ist weiterhin frei, nur halt eben kleiner als vorher. Zusätzlich muss dies alles eben mit Verwaltungsstrukturen verwaltet werden.

Dazu kommen noch die geschilderten Probleme: Delete vergessen, Exceptions usw. die alle zu schwer zu findenden Memoryleaks führen können. Bei Variante 1 kann das nicht passieren, sobald die Funktion beendet wird wird auch das Objekt vom Stack entfernt.

Dave

Alter Hase

  • »Dave« ist der Autor dieses Themas

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

10

13.11.2004, 22:42

bei der 2. variante hat man aber die controlle über die "lebensdauer" seines objektes. wenn ich mein objekt auch noch außerhalb der erstellenden funktion verwenden will, komme ich doch um die 2. variante nicht rum. es sei denn ich arbeite nicht mit zeigern, sondern mach mir ne komplette kopie. was ist besser?

Werbeanzeige