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!
:
Verschoben durch User
Mr. T schrieb: > ist es möglich unter C++ vom Konstruktor einen Rückgabewert zu bekommen? wie soll denn die Verwendung dann aussehen?
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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?
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.
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
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?
Karl Heinz schrieb: > 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. Dem ist doch nichts weiter hinzuzufügen. Oliver
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?
Wobei der Compiler auch einfach mal einen Default- und/oder Copy-Konstruktor bei Bedarf selbst anlegt. Diese arbeiten dann ohne "Fehlerausgang".
Bastler schrieb: > Wobei der Compiler auch einfach mal einen Default- und/oder > Copy-Konstruktor bei Bedarf selbst anlegt. Nur, wenn er darf. Wenn nicht, dann nicht... Oliver
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 | }
|
:
Bearbeitet durch User
Vlad Tepesch schrieb: > schöner wäre eine imho eine statische Memberfunktion. Ob schöner ist Ansichtssache. Die Factory-Funktionen in der Standard Library sind auch keine Member-Funktionen (std::make_shared zB).
Dr. Sommer schrieb: > Alternative: Eine "optional" Klasse verwenden 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. It is not a part of the draft C++14 as of n3797."
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.