Du bist nicht angemeldet.

Werbeanzeige

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

201

07.02.2013, 17:58

Auch Sinn machen würde doch, wenn ich eine Funktion bzw. einen Konstruktor habe, die/der an verschiedenen Stellen eine Exception werfen kann. Dieselbe Funktion fängt die Exception, gibt schon reservierte Ressourcen frei und wirft die Exception erneut.

dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

202

07.02.2013, 18:12

Nope, das wäre ziemlich hässlich, für sowas gibts RAII oder zumindest das Schlüsselwort finally...

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

203

08.02.2013, 17:56

dot, wir würdest du folgendes (ohne std::unique_ptr etc.) lösen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class foo
{
    Object1 *Obj1;
    Object2 *Obj2;

    foo()
    {
        Obj1 = new Object1;
        Obj2 = new Object2;        // was passiert mit Obj1, wenn hier eine Exception geworfen wird, die der Konstruktor nicht fangen und wiederwerfen darf (in diesem Fall könnte er Obj1 freigeben)?
    }
    ~foo()
    {
        delete Obj1;
        delete Obj2;
    }
};

dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

204

08.02.2013, 18:45

Wieso ohne unique_ptr!?

[...] für sowas gibts RAII [...]

...

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

205

08.02.2013, 19:24

Wieso ohne unique_ptr!?


Weil mich interessieren würde, ob es dafür noch eine andere annehmbare Möglichkeit gäbe ;)

drakon

Supermoderator

Beiträge: 6 529

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

206

08.02.2013, 19:49

Ich denke die einzige Möglichkeit wäre alle Exceptions zu fangen und dann den angeforderten Speicher freigeben.

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
class foo
{
    Object1 *Obj1;
    Object2 *Obj2;

    foo()
    {
      Obj1 = nullptr;
      Obj2 = nullptr;
      try
      {
          Obj1 = new Object1;
          Obj2 = new Object2;
      }
      catch(...)
      {
         delete Obj1;
         delete Obj2;
         Obj1 = nullptr;
         Obj2 = nullptr;
      }
    }
    ~foo()
    {
        delete Obj1;
        delete Obj2;
    }
};


Konsequenterweise müsste man die Exception dann aber weiterwerfen, weil das foo nicht initialisiert werden konnte. In dem Falle bräuchte es dann das zurücksetzen auf nullptr nicht mehr.

Das ist aber ein sehr in sich geschlossenes Beispiel und auf keinen Fall eine annehmbare Möglichkeit. ;)

Was ist z.B. wenn du Obj1 oder Obj2 nun neuen Speicher zuweisen willst (in irgendeiner Funktion). Dann müsstest du das gleich wieder machen und dann hast du noch sehr viele Nebenläufigkeiten, die du beachten müsstest.

Annehmbare Lösungen werden immer ein RAII-artiges Konstrukt beinhalten. Ob es selbst geschrieben ist oder versteckt in unique_ptr spielt keine Rolle.

m3xx

Alter Hase

Beiträge: 435

Beruf: Student

  • Private Nachricht senden

207

08.02.2013, 21:34

Sorry für OT: aber mal sone Anfängerfrage: was genau bedeutet "class foo"? class ist ja selbsterklärend aber foo? O.o
Hab kurz gegooglet aber naja so sinnvolles war da jetz nicht bei :/

EDIT: Danke drakon :)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »m3xx« (08.02.2013, 21:48)


drakon

Supermoderator

Beiträge: 6 529

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

208

08.02.2013, 21:40

foo ist ein üblicher default-Bezeichner. Wenn man keine Lust hat ein sinnvolles Beispiel zu machen und einen guten Namen hat, dann nimmt man "foo", "bar" oder "foobar".
Siehe auch hier oder in diesem RFC (<- xD).

dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

209

08.02.2013, 22:09

Wieso ohne unique_ptr!?


Weil mich interessieren würde, ob es dafür noch eine andere annehmbare Möglichkeit gäbe ;)

Mir ist keine bekannt, aber das macht ja auch nix, denn mit RAII gibt es ja bereits eine sehr elegante Lösung...

Architekt

Community-Fossil

Beiträge: 2 490

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

210

08.02.2013, 22:09

foo ist ein üblicher default-Bezeichner. Wenn man keine Lust hat ein sinnvolles Beispiel zu machen und einen guten Namen hat, dann nimmt man "foo", "bar" oder "foobar".
Siehe auch hier oder in diesem RFC (<- xD).

Nicht zu vergessen: quatz
Jedenfalls hab' ich das so kennen gelernt.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Werbeanzeige