C++ "Rückgabewert" vom Konstruktor

Gast #3761054
Lesenswert?

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!
#3761065
Lesenswert?

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.
#3761236
Lesenswert?

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.
#3761256
Lesenswert?

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 ) ...
#3761257
Lesenswert?

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.
#3761289
Lesenswert?

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 #3761357
Lesenswert?

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 #3761417
Lesenswert?

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).
#3761438
Lesenswert?

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 #3761473
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren