C++ "Rückgabewert" vom Konstruktor

Gast #3761054
Hallo zusammen,

ist es möglich unter C++ vom Konstruktor einen Rückgabewert zu bekommen?
Man kann bei beim Instanziieren ja Argumente an den Konstruktor 
übergeben, warum also nicht auch einen Pointer und so mittels Call by 
Reference einen Rückgabewert "durch die Hintertür" erreichen?

viele Grüße!
Natürlich kann man einen Pointer übergeben und der Konstruktor schreibt 
da was rein. Und dann? Das ist aber kein Rückgabewert.
Dass es pfuschig und unübersichtlich (weil gänzlich unerwartet) ist, 
muss ich wohl gar nicht erst erwähnen.
Mr. T schrieb:
> Hallo zusammen,
>
> ist es möglich unter C++ vom Konstruktor einen Rückgabewert zu bekommen?
> Man kann bei beim Instanziieren ja Argumente an den Konstruktor
> übergeben, warum also nicht auch einen Pointer und so mittels Call by
> Reference einen Rückgabewert "durch die Hintertür" erreichen?

Nichts und niemand hindert dich daran, das zu tun. Wie sinnvoll es ist, 
musst du entscheiden. Dem Compiler ist das egal, solange du dich im 
Rahmen der Sprachregeln bewegst.

Aber einen Returnwert, so wie bei normalen Funktionen, gibt es bei einem 
Konstruktor nicht.
Manchmal ist es halt nötig (z.B. wenn man keine Exceptions nehmen kann, 
und im ctor etwas schief gehen kann).

Eine Alternative zu einem übergebenen Pointer oder Referenz zur 
Rückmeldung wäre noch ein interner Status, der je nach Erfolg des ctor 
gesetzt wird (evtl. auch von anderen Methoden später) und mit einer 
getStatus() o.ä. abgefragt werden kann.

PS: das hat dann eine gewisse Ählichkeit zu errno, nur halt ein Exemplar 
pro Objekt.
halt hinterher (vorher geht  ja nicht :-)
1
class Cx
2
{
3
public:
4

5
    enum eStatus
6
    {
7
        eStatusOk,
8
        eStatusOioioi,
9
        ...
10
    };
11

12
    eStatus getStatus()
13
    {
14
        return status;
15
    }
16

17
    Cx()
18
       : status(eStatusOioioi)
19
    {
20
        ... initiiaze something ...
21
        if( ichhabemigraene ) return;
22
        status = eStatusOk;´
23
    }
24

25
private:
26
    eStatus   status;
27
};
28

29
   Cx x(param);
30
   if( x.getStatus()!=Cx::eStatusOk ) ...
Peter II schrieb:
> Klaus Wachtler schrieb:
>> Manchmal ist es halt nötig (z.B. wenn man keine Exceptions nehmen kann,
>> und im ctor etwas schief gehen kann).
>
> schon klar, aber wie sollte man es dann aufrufen?
>
>
> Cx x(param)
>
> wie würde man dann jetzt den Returnwert abfragen wollen?

Peter, oben beschreibt doch der TE dass er es über einen Pointer lösen 
will. Natürlich hat ein Konstruktor keinen Rückgabewert.
Peter II schrieb:
> cyblord ---- schrieb:
>> Peter, oben beschreibt doch der TE dass er es über einen Pointer lösen
>> will.
> nein, er will es nicht über den Umweg Parameter lösen

Er schreibt aber genau das hier:

> Man kann bei beim Instanziieren ja Argumente an den Konstruktor
> übergeben, warum also nicht auch einen Pointer und so mittels Call by
> Reference einen Rückgabewert "durch die Hintertür" erreichen?
Gast
In vielerlei Hinsicht ist ein Konstruktor eine ganz einfache Funktion. 
Natürlich kannst Du der auch einen Zeiger oder eine Adressreferenz 
mitgeben.

Mir stellt sich dabei aber die einfache Frage: Was soll's?

Was hindert Dich daran das Ergebnis in der Klasse zu speichern und über:
Klassenreferenz.Rueckgabewert zu ermitteln?
Gast
Alternative: Eine "optional" Klasse verwenden (wie zB Boost.Optional, 
kann man sich auch leicht selber bauen) und eine Factory-Funktion:
1
class MyClass;
2

3
// Factory-Funktion
4
inline optional<MyClass> createMyClass (int a, int b, int c);
5

6
class MyClass {
7
  friend optional<MyClass> createMyClass (int a, int b, int c);
8
  public:
9
    void doSomething ();
10
  private:
11
    // Konstruktor private, und Factory-Funktion ist "friend"; somit können nur über die Factory-Funktion Instanzen erstellt werden.
12
    MyClass (int a, int b, int c);
13
};
14

15
inline optional<MyClass> createMyClass (int a, int b, int c) {
16
  // Parameter gültig?
17
  if (a < 42 && b < c)
18
    // Instanz erstellen und zurückgeben
19
    return optional<MyClass> ( MyClass { a, b, c });
20
  // Parameter ungültig => Nichts zurückgeben
21
  return;
22
}
23

24
int main () {
25
  // Factory aufrufen zum Instanz erstellen...
26
  auto x = createMyClass ();
27
  // Instanz erstellt?
28
  if (x)
29
    x->doSomething ();
30
  else
31
    std::cout << "Fehler beim Anlegen der Instanz von MyClass.\n";
32
}
So spart man sich hässliche Dinge wie Output-Parameter und zusätzliche 
Member in der Klasse (Speicher-Verbrauch).
Dr. Sommer schrieb:
> Alternative: Eine "optional" Klasse verwenden (wie zB Boost.Optional,
> kann man sich auch leicht selber bauen) und eine Factory-Funktion:

schöner wäre eine imho eine statische Memberfunktion. Da entfällt auch 
die leidliche friend-Deklaration.
1
class MyClass {
2
  public:
3
    void doSomething ();
4

5
    static optional<MyClass> create(int a, int b, int c) 
6
    {
7
      // Parameter gültig?
8
      if (a < 42 && b < c){
9
        // Instanz erstellen und zurückgeben
10
        return optional<MyClass> ( MyClass { a, b, c });
11
      }
12
      // Parameter ungültig => Nichts zurückgeben
13
      return;
14
    }
15

16
  private:
17
    // Konstruktor privat; somit können nur über die Factory-Funktion Instanzen erstellt werden.
18
    MyClass (int a, int b, int c);
19
};
20

21
int main () {
22
  // Factory aufrufen zum Instanz erstellen...
23
  auto x = MyClass::create (1,2,3);
24
  // Instanz erstellt?
25
  if (x)
26
    x->doSomething ();
27
  else
28
    std::cout << "Fehler beim Anlegen der Instanz von MyClass.\n";
29
}
Gast
A. K. schrieb:
> Wie verbreitet ist das? Eine Doku sagt: "After reviewing national body
> comments to N3690, this library component was voted out from C++14
> working paper into a separate Technical Specification.
Ja, total bescheuert. Boost.Optional kann man aber immer 
nachinstallieren oder es eben selber implementieren.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.