Initialisieren von einer Klasseninstanz
-
Hallo zusammen,
ich habe ein Problem beim Initialisieren von einer Klasseninstanz. Über eine Variable soll geprüft werden ob die Instanz mit Konstruktor1 oder Konstruktor2 initialisert werden soll.
Wenn ich aber Folgedes aufrufe:if (temp) Klasse Instanzname(Konstruktor1); else Klasse Instanzname(Konstruktor2); Instanzname.methode(); //<- hier kennt er den Bezeichner nichtbekomme ich die Fehlermeldung: nichtdeklarierter Bezeichner.
Das liegt ja daran, das die Klasse in einer If-Schleife initialisiert wird und er deshalb wohl davon ausgeht, dass die Instanz eventuell nicht exestiert.
Ich habe es mit dem ? Operator probiert aber hatte lieder auch keinen Erfolg.
Kann mir bitte jemand sagen, wie ich das ganze umstellen muss, dass es funktioniert?Vielen Dank
-
Wenn man es so schreibt, siehst du es vielleicht direkt.
if (temp) { Klasse Instanzname(Konstruktor1); } else { Klasse Instanzname(Konstruktor2); } Instanzname.methode(); // Instanzname ist hier schon längst out of scope gelaufen.Falls deine Klasse default constructible ist und nen Zuweisungsoperator hat:
Klasse Instanzname; if (temp) Instanzname = Klasse(Konstruktor1); else Instanzname = Klasse(Konstruktor2); Instanzname.methode();Wenn das nicht geht, wirst du um so etwas in der Art hier wohl nicht drumherum kommen:
typedef std::unique_ptr<Klasse> KlassenPtr; KlassenPtr p; if (temp) p = KlassenPtr(new Klasse(Konstruktor1)); else n = KlassenPtr(new Klasse(Konstruktor2)), KlassenPtr->methode();Ich gehe mal davon aus, dass Konstruktor1 und Konstruktor2 bei dir Variablen mit verschiedenen Datentypen sind. Dann solltest du sie aber auch hier im Minimalbeispiel nicht KonstruktorN nennen, weil sie ja keine ctors sind sondern Parameter für eben jene, die den Compiler dazu bringen jeweils die passende Überladung zu benutzen.
Achja, und natürlich: http://www.if-schleife.de/

Edit: Wenn Konstruktor1 und Konstruktor2 vom gleichen Typ sind und nur unterschiedliche Werte halten (wie die ints im Beispiel von KN4CK3R), kannst du auch sowas machen:
Klasse Instanzname(temp ? Konstruktor1 : Konstruktor2); Instanzname.methode();Um zu wissen, um was es sich da bei dir handelt, wäre ein *kompilierbares* Minimalbeispiel halt toll gewesen.
-
Instanzname ist nur im Scope des if Blocks gültig.
Du könntest es mit Zeigern lösenKlasse *instanzname; if (temp) instanzname = new Klasse(1); else instanzname = new Klasse(2); instanzname->methode(); delete instanzname;greetz KN4CK3R
-
Hi,
die Instanz von Klasse besteht auf diese Art nur bis zum verlassen des If-Rumpfs. Mit new initalisierte Objekte wären auch nach dem Rumpf noch gültig, der Zugriff könnte über Pointer oder Referenzen erfolgen - welche schon vor dem If-Block oder Rumpf bestehen.
Bedenke aber auch die Aufräumarbeiten oder verwende intelligente Zeiger.
Gruss
Edit:
Tja und ein paar Sekunden zuvor der passende Code zur Erklärung:KN4CK3R schrieb:
Instanzname ist nur im Scope des if Blocks gültig.
Du könntest es mit Zeigern lösenKlasse *instanzname; if (temp) instanzname = new Klasse(1); else instanzname = new Klasse(2); instanzname->methode(); delete instanzname;greetz KN4CK3R
-
Vielen Dank für die schnellen Hilfen! Werde das Ganze gleich mal testen

-
Läuft alles. Vielen Dank Problem gelöst

-
KN4CK3R schrieb:
Du könntest es mit Zeigern lösen
Klasse *instanzname; if (temp) instanzname = new Klasse(1); else instanzname = new Klasse(2); instanzname->methode(); delete instanzname;Nö, das ist Mist ohne
unique_ptr.So ein Hack mit
newals Lösung deutet übrigens darauf hin, dass das Problem mit besserem Design vermeidbar wäre. In welchem Zusammenhang musst du denn zwischen zwei Konstruktoren wählen? Wie sehen die aus und was ist die Bedingung?
-
Klasse Instanzname = temp ? Klasse(Konstruktor1) : Klasse(Konstruktor2); ...oder
auto undsoweiter = [&](Klasse& Instanzname){ ... }; if (temp) { Klasse Instanzname (Konstruktor1); undsoweiter(Instanzname); } else { Klasse Instanzname (Konstruktor2); undsoweiter(Instanzname); }oder
boost::optional<Klasse> dingen; if (temp) { dingen = Klasse(Konstruktor1); } else { dingen = Klasse(Konstruktor2); } Klasse& Instanz = *dingen; ...oder
std::unique_ptr<Klasse> dingen; if (temp) { dingen.reset(new Klasse(Konstruktor1)); } else { dingen.reset(new Klasse(Konstruktor2)); } Klasse& Instanz = *dingen; ...oder
std::vector<Klasse> dingen; if (temp) { dingen.emplace_back(Konstruktor1); } else { dingen.emplace_back(Konstruktor2); } Klasse& Instanz = dingen[0]; ......
Mehr Kontext bei der Frage wär jetzt praktisch gewesen.
-
krümelkacker schrieb:
Klasse Instanzname = temp ? Klasse(Konstruktor1) : Klasse(Konstruktor2);Oh, stimmt. So ist's sehr hübsch.

Jetzt hat mich dabei interessiert, ob das dann auch ohne Aufruf vom copy-ctor auskommt.#include <iostream> struct Foo { Foo(int) { std::cout << "Foo(int)" << std::endl; } Foo(int, int) { std::cout << "Foo(int, int)" << std::endl; } Foo(const Foo&) { std::cout << "Foo(const Foo&)" << std::endl; } Foo& operator=(const Foo&) { std::cout << "operator=(const Foo&)" << std::endl; return *this;} }; int main() { int input; std::cin >> input; Foo fa(1); std::cout << "---" << std::endl; Foo fb = Foo(1); std::cout << "---" << std::endl; Foo fc = input == 1 ? Foo(1) : Foo(1, 2); }Beim GCC tut es das:
1 Foo(int) --- Foo(int) --- Foo(int)Interessanterweise macht MSVC 2010 Express (Release) das anders:
1 Foo(int) --- Foo(int) --- Foo(int) Foo(const Foo&)